开发文章

VC获取网卡MAC、硬盘序列号、CPU ID、BIOS编号

以下代码可以取得系统特征码(网卡MAC、硬盘序列号、CPU ID、BIOS编号)
 

  1. BYTE szSystemInfo[4096]; // 在程序执行完毕后,此处存储取得的系统特征码   
  2.     UINT uSystemInfoLen = 0; // 在程序执行完毕后,此处存储取得的系统特征码的长度   
  3.   
  4.     // 网卡 MAC 地址,注意: MAC 地址是可以在注册表中修改的   
  5.     {   
  6.         UINT uErrorCode = 0;   
  7.         IP_ADAPTER_INFO iai;   
  8.         ULONG uSize = 0;   
  9.         DWORD dwResult = GetAdaptersInfo( &iai, &uSize );   
  10.         if( dwResult == ERROR_BUFFER_OVERFLOW )   
  11.         {   
  12.             IP_ADAPTER_INFO* piai = ( IP_ADAPTER_INFO* )HeapAlloc( GetProcessHeap( ), 0, uSize );   
  13.             if( piai != NULL )   
  14.             {   
  15.                 dwResult = GetAdaptersInfo( piai, &uSize );   
  16.                 if( ERROR_SUCCESS == dwResult )   
  17.                 {   
  18.                     IP_ADAPTER_INFO* piai2 = piai;   
  19.                     while( piai2 != NULL && ( uSystemInfoLen + piai2->AddressLength ) < 4096U )   
  20.                     {   
  21.                         CopyMemory( szSystemInfo + uSystemInfoLen, piai2->Address, piai2->AddressLength );   
  22.                         uSystemInfoLen += piai2->AddressLength;   
  23.                         piai2 = piai2->Next;                           
  24.                     }   
  25.                 }   
  26.                 else  
  27.                 {   
  28.                     uErrorCode = 0xF0000000U + dwResult;   
  29.                 }   
  30.                 VERIFY( HeapFree( GetProcessHeap( ), 0, piai ) );   
  31.             }   
  32.             else  
  33.             {   
  34.                 return FALSE;   
  35.             }   
  36.         }   
  37.         else  
  38.         {   
  39.             uErrorCode = 0xE0000000U + dwResult;   
  40.         }   
  41.         if( uErrorCode != 0U )   
  42.         {   
  43.             return FALSE;   
  44.         }   
  45.     }   

// 硬盘序列号,注意:有的硬盘没有序列号
 

  1. //h文件中的代码   
  2. #include "iostream"   
  3. #include "winioctl.h"   
  4.   
  5. #define  IDE_ATAPI_IDENTIFY  0xA1  //  Returns ID sector for ATAPI.    
  6. #define  IDE_ATA_IDENTIFY    0xEC  //  Returns ID sector for ATA.    
  7. #define  IOCTL_GET_DRIVE_INFO   0x0007c088    
  8. #define  IOCTL_GET_VERSION          0x00074080    
  9.   
  10. typedef struct _GETVERSIONOUTPARAMS    
  11. {    
  12.     BYTE bVersion;      // Binary driver version.    
  13.     BYTE bRevision;     // Binary driver revision.    
  14.     BYTE bReserved;     // Not used.    
  15.     BYTE bIDEDeviceMap; // Bit map of IDE devices.    
  16.     DWORD fCapabilities; // Bit mask of driver capabilities.    
  17.     DWORD dwReserved[4]; // For future use.    
  18. } GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;   
  19.   
  20. //cpp文件中的代码   
  21. // Windows NT/2000/XP下读取IDE设备信息    
  22. bool GetHardwarePhysical_IDE_Info_NT(HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP, PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum, PDWORD lpcbBytesReturned)   
  23. {      
  24.     // 为读取设备信息准备参数      
  25.     pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;      
  26.     pSCIP -> irDriveRegs.bFeaturesReg = 0;      
  27.     pSCIP -> irDriveRegs.bSectorCountReg = 1;      
  28.     pSCIP -> irDriveRegs.bSectorNumberReg = 1;      
  29.     pSCIP -> irDriveRegs.bCylLowReg = 0;      
  30.     pSCIP -> irDriveRegs.bCylHighReg = 0;      
  31.   
  32.     // 计算驱动器位置      
  33.     pSCIP -> irDriveRegs.bDriveHeadReg = 0xA0 | ((bDriveNum & 1) << 4);      
  34.   
  35.     // 设置读取命令      
  36.     pSCIP -> irDriveRegs.bCommandReg = bIDCmd;      
  37.     pSCIP -> bDriveNumber = bDriveNum;      
  38.     pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;      
  39.   
  40.     // 读取驱动器信息      
  41.     return ( DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_GET_DRIVE_INFO,    (LPVOID) pSCIP, sizeof(SENDCMDINPARAMS) - 1, (LPVOID) pSCOP,    sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1, lpcbBytesReturned, NULL) ) ? true : false;      
  42. }   
  43. // Windows NT/2000/XP下读取IDE硬盘序列号      
  44. bool GetHDD_SN_forWinNt(DWORD * buffer)      
  45. {      
  46.     BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];      
  47.     bool bFlag = false;      
  48.     int  drive = 0;      
  49.     char driveName [256];      
  50.     HANDLE hPhysicalDriveIOCTL = 0;          
  51.   
  52.     sprintf (driveName, "\\\\.\\PhysicalDrive%d", drive);      
  53.     //  Windows NT/2000/XP下创建文件需要管理员权限      
  54.     hPhysicalDriveIOCTL = CreateFileA (driveName,      
  55.         GENERIC_READ | GENERIC_WRITE,       
  56.         FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,      
  57.         OPEN_EXISTING, 0, NULL);      
  58.   
  59.     if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)      
  60.     {      
  61.         GETVERSIONOUTPARAMS VersionParams;      
  62.         DWORD               cbBytesReturned = 0;      
  63.   
  64.         // 得到驱动器的IO控制器版本      
  65.         memset ((void*) &VersionParams, 0, sizeof(VersionParams));      
  66.         if(::DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_GET_VERSION,      
  67.             NULL, 0, &VersionParams,      
  68.             sizeof(VersionParams),      
  69.             &cbBytesReturned, NULL) )      
  70.         {              
  71.             if (VersionParams.bIDEDeviceMap > 0)      
  72.             {      
  73.                 BYTE             bIDCmd = 0;   // IDE或者ATAPI识别命令      
  74.                 SENDCMDINPARAMS  scip;      
  75.   
  76.                 // 如果驱动器是光驱,采用命令IDE_ATAPI_IDENTIFY, command,      
  77.                 // 否则采用命令IDE_ATA_IDENTIFY读取驱动器信息      
  78.                 bIDCmd = (VersionParams.bIDEDeviceMap >> drive & 0x10)?   IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;      
  79.   
  80.                 memset (&scip, 0, sizeof(scip));      
  81.                 memset (IdOutCmd, 0, sizeof(IdOutCmd));      
  82.                 // 获取驱动器信息      
  83.                 if (GetHardwarePhysical_IDE_Info_NT(hPhysicalDriveIOCTL,       
  84.                     &scip,       
  85.                     (PSENDCMDOUTPARAMS)&IdOutCmd,       
  86.                     (BYTE) bIDCmd,      
  87.                     (BYTE) drive,      
  88.                     &cbBytesReturned))      
  89.                 {      
  90.                     int m = 0;      
  91.                     USHORT *pIdSector = (USHORT *)      
  92.                         ((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer;      
  93.   
  94.                     for (m = 0; m < 256; m++)      
  95.                         buffer[m] = pIdSector [m];      
  96.                     bFlag = false;  // 读取硬盘信息成功      
  97.                 }      
  98.             }      
  99.         }      
  100.         ::CloseHandle (hPhysicalDriveIOCTL);  // 关闭句柄      
  101.     }      
  102.     return bFlag;      
  103. }      
  104. // Windows NT/2000/XP系统下,将双字类型(DWORD)的硬盘信息转换为字符类型(char)      
  105. std::string physical_info_dword_to_char(DWORD diskdata [256], int firstIndex, int lastIndex)   
  106. {      
  107.     char string [1024];      
  108.     int index = 0;      
  109.     int position = 0;      
  110.   
  111.     // 按照高字节在前,低字节在后的顺序将双字中的低字存入到字符串string中       
  112.     for (index = firstIndex; index <= lastIndex; index++)      
  113.     {      
  114.         // 存入低字中的高字节      
  115.         string [position] = (char) (diskdata [index] / 256);      
  116.         position++;      
  117.         // 存入低字中的低字节      
  118.         string [position] = (char) (diskdata [index] % 256);      
  119.         position++;      
  120.     }      
  121.     //  添加字符串结束标志      
  122.     string [position] = '\0';      
  123.   
  124.     //  删除字符串中空格      
  125.     for (index = position - 1; index > 0 && ' ' == string [index]; index--)      
  126.         string [index] = '\0';      
  127.   
  128.     return string;      
  129. }    
  130.   
  131.     //调用方法   
  132.     DWORD  dwBuf[256];   
  133.     char m_buffer[222];   
  134.   
  135.     GetHDD_SN_forWinNt(dwBuf);   
  136.     strcpy(m_buffer, physical_info_dword_to_char(dwBuf, 10, 19).c_str());     
  137.     ::MessageBoxA(m_hWnd, m_buffer, "硬盘序列号", MB_OK);  


// CPU ID

  1. {   
  2.         BOOL bException = FALSE;   
  3.         BYTE szCpu[16]  = { 0 };   
  4.         UINT uCpuID     = 0U;   
  5.   
  6.         __try    
  7.         {   
  8.             _asm    
  9.             {   
  10.                 mov eax, 0   
  11.                 cpuid   
  12.                 mov dword ptr szCpu[0], ebx   
  13.                 mov dword ptr szCpu[4], edx   
  14.                 mov dword ptr szCpu[8], ecx   
  15.                 mov eax, 1   
  16.                 cpuid   
  17.                 mov uCpuID, edx   
  18.             }   
  19.         }   
  20.         __except( EXCEPTION_EXECUTE_HANDLER )   
  21.         {   
  22.             bException = TRUE;   
  23.         }   
  24.            
  25.         if( !bException )   
  26.         {   
  27.             CopyMemory( szSystemInfo + uSystemInfoLen, &uCpuID, sizeofUINT ) );   
  28.             uSystemInfoLen += sizeofUINT );   
  29.   
  30.             uCpuID = strlen( ( char* )szCpu );   
  31.             CopyMemory( szSystemInfo + uSystemInfoLen, szCpu, uCpuID );   
  32.             uSystemInfoLen += uCpuID;   
  33.         }   
  34.     }   
  35.   

// BIOS 编号,支持 AMI, AWARD, PHOENIX
 

  1. {   
  2.         SIZE_T ssize;    
  3.   
  4.         LARGE_INTEGER so;    
  5.         so.LowPart=0x000f0000;   
  6.         so.HighPart=0x00000000;    
  7.         ssize=0xffff;    
  8.         wchar_t strPH[30]=L\\device\\physicalmemory;    
  9.   
  10.         DWORD ba=0;   
  11.   
  12.         UNICODE_STRING struniph;    
  13.         struniph.Buffer=strPH;    
  14.         struniph.Length=0x2c;    
  15.         struniph.MaximumLength =0x2e;    
  16.   
  17.         OBJECT_ATTRIBUTES obj_ar;    
  18.         obj_ar.Attributes =64;   
  19.         obj_ar.Length =24;   
  20.         obj_ar.ObjectName=&struniph;   
  21.         obj_ar.RootDirectory=0;    
  22.         obj_ar.SecurityDescriptor=0;    
  23.         obj_ar.SecurityQualityOfService =0;    
  24.   
  25.         HMODULE hinstLib = LoadLibrary("ntdll.dll");    
  26.         ZWOS ZWopenS=(ZWOS)GetProcAddress(hinstLib,"ZwOpenSection");    
  27.         ZWMV ZWmapV=(ZWMV)GetProcAddress(hinstLib,"ZwMapViewOfSection");    
  28.         ZWUMV ZWunmapV=(ZWUMV)GetProcAddress(hinstLib,"ZwUnmapViewOfSection");    
  29.            
  30.         //调用函数,对物理内存进行映射    
  31.         HANDLE hSection;    
  32.         if( 0 == ZWopenS(&hSection,4,&obj_ar) &&    
  33.             0 == ZWmapV(    
  34.             ( HANDLE )hSection,   //打开Section时得到的句柄    
  35.             ( HANDLE )0xFFFFFFFF, //将要映射进程的句柄,    
  36.             &ba,                  //映射的基址    
  37.             0,   
  38.             0xFFFF,               //分配的大小    
  39.             &so,                  //物理内存的地址    
  40.             &ssize,               //指向读取内存块大小的指针    
  41.             1,                    //子进程的可继承性设定    
  42.             0,                    //分配类型    
  43.             2                     //保护类型    
  44.             ) )   
  45.         //执行后会在当前进程的空间开辟一段64k的空间,并把f000:0000到f000:ffff处的内容映射到这里    
  46.         //映射的基址由ba返回,如果映射不再有用,应该用ZwUnmapViewOfSection断开映射    
  47.         {   
  48.             BYTE* pBiosSerial = ( BYTE* )ba;   
  49.             UINT uBiosSerialLen = FindAwardBios( &pBiosSerial );   
  50.             if( uBiosSerialLen == 0U )   
  51.             {   
  52.                 uBiosSerialLen = FindAmiBios( &pBiosSerial );   
  53.                 if( uBiosSerialLen == 0U )   
  54.                 {   
  55.                     uBiosSerialLen = FindPhoenixBios( &pBiosSerial );   
  56.                 }   
  57.             }   
  58.             if( uBiosSerialLen != 0U )   
  59.             {   
  60.                 CopyMemory( szSystemInfo + uSystemInfoLen, pBiosSerial, uBiosSerialLen );   
  61.                 uSystemInfoLen += uBiosSerialLen;   
  62.             }   
  63.             ZWunmapV( ( HANDLE )0xFFFFFFFF, ( void* )ba );   
  64.         }   
  65.     }   
  66.     // 完毕, 系统特征码已取得   

以下是其中用到的某些结构及函数的定义:
 

  1. #define  FILE_DEVICE_SCSI              0x0000001b   
  2. #define  IOCTL_SCSI_MINIPORT_IDENTIFY  ( ( FILE_DEVICE_SCSI << 16 ) + 0x0501 )   
  3.   
  4. #define  IOCTL_SCSI_MINIPORT 0x0004D008  //  see NTDDSCSI.H for definition   
  5.   
  6. #define  IDENTIFY_BUFFER_SIZE  512   
  7. #define  SENDIDLENGTH  ( sizeof( SENDCMDOUTPARAMS ) + IDENTIFY_BUFFER_SIZE )   
  8.   
  9. #define  IDE_ATAPI_IDENTIFY  0xA1  //  Returns ID sector for ATAPI.   
  10. #define  IDE_ATA_IDENTIFY    0xEC  //  Returns ID sector for ATA.   
  11. #define  DFP_RECEIVE_DRIVE_DATA   0x0007c088   
  12.   
  13. typedef struct _IDSECTOR   
  14. {   
  15.     USHORT  wGenConfig;   
  16.     USHORT  wNumCyls;   
  17.     USHORT  wReserved;   
  18.     USHORT  wNumHeads;   
  19.     USHORT  wBytesPerTrack;   
  20.     USHORT  wBytesPerSector;   
  21.     USHORT  wSectorsPerTrack;   
  22.     USHORT  wVendorUnique[3];   
  23.     CHAR    sSerialNumber[20];   
  24.     USHORT  wBufferType;   
  25.     USHORT  wBufferSize;   
  26.     USHORT  wECCSize;   
  27.     CHAR    sFirmwareRev[8];   
  28.     CHAR    sModelNumber[40];   
  29.     USHORT  wMoreVendorUnique;   
  30.     USHORT  wDoubleWordIO;   
  31.     USHORT  wCapabilities;   
  32.     USHORT  wReserved1;   
  33.     USHORT  wPIOTiming;   
  34.     USHORT  wDMATiming;   
  35.     USHORT  wBS;   
  36.     USHORT  wNumCurrentCyls;   
  37.     USHORT  wNumCurrentHeads;   
  38.     USHORT  wNumCurrentSectorsPerTrack;   
  39.     ULONG   ulCurrentSectorCapacity;   
  40.     USHORT  wMultSectorStuff;   
  41.     ULONG   ulTotalAddressableSectors;   
  42.     USHORT  wSingleWordDMA;   
  43.     USHORT  wMultiWordDMA;   
  44.     BYTE    bReserved[128];   
  45. } IDSECTOR, *PIDSECTOR;   
  46.   
  47. typedef struct _DRIVERSTATUS   
  48.   
  49. {   
  50.     BYTE  bDriverError;  //  Error code from driver, or 0 if no error.   
  51.     BYTE  bIDEStatus;    //  Contents of IDE Error register.   
  52.     //  Only valid when bDriverError is SMART_IDE_ERROR.   
  53.     BYTE  bReserved[2];  //  Reserved for future expansion.   
  54.     DWORD  dwReserved[2];  //  Reserved for future expansion.   
  55. } DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;   
  56.   
  57. typedef struct _SENDCMDOUTPARAMS   
  58. {   
  59.     DWORD         cBufferSize;   //  Size of bBuffer in bytes   
  60.     DRIVERSTATUS  DriverStatus;  //  Driver status structure.   
  61.     BYTE          bBuffer[1];    //  Buffer of arbitrary length in which to store the data read from the                                                       // drive.   
  62. } SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;   
  63.   
  64. typedef struct _SRB_IO_CONTROL   
  65. {   
  66.     ULONG HeaderLength;   
  67.     UCHAR Signature[8];   
  68.     ULONG Timeout;   
  69.     ULONG ControlCode;   
  70.     ULONG ReturnCode;   
  71.     ULONG Length;   
  72. } SRB_IO_CONTROL, *PSRB_IO_CONTROL;   
  73.   
  74. typedef struct _IDEREGS   
  75. {   
  76.     BYTE bFeaturesReg;       // Used for specifying SMART "commands".   
  77.     BYTE bSectorCountReg;    // IDE sector count register   
  78.     BYTE bSectorNumberReg;   // IDE sector number register   
  79.     BYTE bCylLowReg;         // IDE low order cylinder value   
  80.     BYTE bCylHighReg;        // IDE high order cylinder value   
  81.     BYTE bDriveHeadReg;      // IDE drive/head register   
  82.     BYTE bCommandReg;        // Actual IDE command.   
  83.     BYTE bReserved;          // reserved for future use.  Must be zero.   
  84. } IDEREGS, *PIDEREGS, *LPIDEREGS;   
  85.   
  86. typedef struct _SENDCMDINPARAMS   
  87. {   
  88.     DWORD     cBufferSize;   //  Buffer size in bytes   
  89.     IDEREGS   irDriveRegs;   //  Structure with drive register values.   
  90.     BYTE bDriveNumber;       //  Physical drive number to send    
  91.     //  command to (0,1,2,3).   
  92.     BYTE bReserved[3];       //  Reserved for future expansion.   
  93.     DWORD     dwReserved[4]; //  For future use.   
  94.     BYTE      bBuffer[1];    //  Input buffer.   
  95. } SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;   
  96.   
  97. typedef struct _GETVERSIONOUTPARAMS   
  98. {   
  99.     BYTE bVersion;      // Binary driver version.   
  100.     BYTE bRevision;     // Binary driver revision.   
  101.     BYTE bReserved;     // Not used.   
  102.     BYTE bIDEDeviceMap; // Bit map of IDE devices.   
  103.     DWORD fCapabilities; // Bit mask of driver capabilities.   
  104.     DWORD dwReserved[4]; // For future use.   
  105. } GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;   
  106.   
  107. //////////////////////////////////////////////////////////////////////   
  108.   
  109. //结构定义    
  110. typedef struct _UNICODE_STRING    
  111. {    
  112.     USHORT  Length;//长度    
  113.     USHORT  MaximumLength;//最大长度    
  114.     PWSTR  Buffer;//缓存指针    
  115. } UNICODE_STRING,*PUNICODE_STRING;    
  116.   
  117. typedef struct _OBJECT_ATTRIBUTES    
  118. {    
  119.     ULONG Length;//长度 18h    
  120.     HANDLE RootDirectory;//  00000000    
  121.     PUNICODE_STRING ObjectName;//指向对象名的指针    
  122.     ULONG Attributes;//对象属性00000040h    
  123.     PVOID SecurityDescriptor;        // Points to type SECURITY_DESCRIPTOR,0    
  124.     PVOID SecurityQualityOfService;  // Points to type SECURITY_QUALITY_OF_SERVICE,0    
  125. } OBJECT_ATTRIBUTES;    
  126. typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;    
  127.   
  128. //函数指针变量类型   
  129. typedef DWORD  (__stdcall *ZWOS )( PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES);    
  130. typedef DWORD  (__stdcall *ZWMV )( HANDLE,HANDLE,PVOID,ULONG,ULONG,PLARGE_INTEGER,PSIZE_T,DWORD,ULONG,ULONG);    
  131. typedef DWORD  (__stdcall *ZWUMV )( HANDLE,PVOID);    
  132.   
  133. BOOL WinNTHDSerialNumAsScsiRead( BYTE* dwSerial, UINT* puSerialLen, UINT uMaxSerialLen )   
  134. {   
  135.     BOOL bInfoLoaded = FALSE;   
  136.        
  137.     forint iController = 0; iController < 2; ++ iController )   
  138.     {   
  139.         HANDLE hScsiDriveIOCTL = 0;   
  140.         char   szDriveName[256];   
  141.            
  142.         //  Try to get a handle to PhysicalDrive IOCTL, report failure   
  143.         //  and exit if can't.   
  144.         sprintf( szDriveName, "\\\\.\\Scsi%d:", iController );   
  145.   
  146.         //  Windows NT, Windows 2000, any rights should do   
  147.         hScsiDriveIOCTL = CreateFile( szDriveName,   
  148.             GENERIC_READ | GENERIC_WRITE,    
  149.             FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,   
  150.             OPEN_EXISTING, 0, NULL);   
  151.   
  152.         // if (hScsiDriveIOCTL == INVALID_HANDLE_VALUE)   
  153.         //    printf ("Unable to open SCSI controller %d, error code: 0x%lX\n",   
  154.         //            controller, GetLastError ());   
  155.            
  156.         if( hScsiDriveIOCTL != INVALID_HANDLE_VALUE )   
  157.         {   
  158.             int iDrive = 0;   
  159.             for( iDrive = 0; iDrive < 2; ++ iDrive )   
  160.             {   
  161.                 char szBuffer[sizeof( SRB_IO_CONTROL ) + SENDIDLENGTH] = { 0 };   
  162.   
  163.                 SRB_IO_CONTROL* p = ( SRB_IO_CONTROL* )szBuffer;   
  164.                 SENDCMDINPARAMS* pin = ( SENDCMDINPARAMS* )( szBuffer + sizeof( SRB_IO_CONTROL ) );   
  165.                 DWORD dwResult;   
  166.   
  167.                 p->HeaderLength = sizeof( SRB_IO_CONTROL );   
  168.                 p->Timeout = 10000;   
  169.                 p->Length = SENDIDLENGTH;   
  170.                 p->ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;   
  171.                 strncpy( ( char* )p->Signature, "SCSIDISK", 8 );   
  172.   
  173.                 pin->irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;   
  174.                 pin->bDriveNumber = iDrive;   
  175.                    
  176.                 if( DeviceIoControl( hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT,    
  177.                     szBuffer,   
  178.                     sizeof( SRB_IO_CONTROL ) + sizeof( SENDCMDINPARAMS ) - 1,   
  179.                     szBuffer,   
  180.                     sizeof( SRB_IO_CONTROL ) + SENDIDLENGTH,   
  181.                     &dwResult, NULL ) )   
  182.                 {   
  183.                     SENDCMDOUTPARAMS* pOut = ( SENDCMDOUTPARAMS* )( szBuffer + sizeof( SRB_IO_CONTROL ) );   
  184.                     IDSECTOR* pId = ( IDSECTOR* )( pOut->bBuffer );   
  185.                     if( pId->sModelNumber[0] )   
  186.                     {   
  187.                         if( * puSerialLen + 20U <= uMaxSerialLen )   
  188.                         {   
  189.                             // 序列号   
  190.                             CopyMemory( dwSerial + * puSerialLen, ( ( USHORT* )pId ) + 10, 20 );   
  191.   
  192.                             // Cut off the trailing blanks   
  193.                             forUINT i = 20; i != 0U && ' ' == dwSerial[* puSerialLen + i - 1]; -- i )  
  194.                             {}  
  195.                             * puSerialLen += i;  
  196.  
  197.                             // 型号  
  198.                             CopyMemory( dwSerial + * puSerialLen, ( ( USHORT* )pId ) + 27, 40 );  
  199.                             // Cut off the trailing blanks  
  200.                             for( i = 40; i != 0U && ' ' == dwSerial[* puSerialLen + i - 1]; -- i )  
  201.                             {}  
  202.                             * puSerialLen += i;  
  203.  
  204.                             bInfoLoaded = TRUE;  
  205.                         }  
  206.                         else  
  207.                         {  
  208.                             ::CloseHandle( hScsiDriveIOCTL );  
  209.                             return bInfoLoaded;  
  210.                         }  
  211.                     }  
  212.                 }  
  213.             }  
  214.             ::CloseHandle( hScsiDriveIOCTL );  
  215.         }  
  216.     }  
  217.     return bInfoLoaded;  
  218. }  
  219.  
  220. BOOL DoIdentify( HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,  
  221.                  PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum,  
  222.                  PDWORD lpcbBytesReturned )  
  223. {  
  224.     // Set up data structures for IDENTIFY command.  
  225.     pSCIP->cBufferSize                  = IDENTIFY_BUFFER_SIZE;  
  226.     pSCIP->irDriveRegs.bFeaturesReg     = 0;  
  227.     pSCIP->irDriveRegs.bSectorCountReg  = 1;  
  228.     pSCIP->irDriveRegs.bSectorNumberReg = 1;  
  229.     pSCIP->irDriveRegs.bCylLowReg       = 0;  
  230.     pSCIP->irDriveRegs.bCylHighReg      = 0;  
  231.       
  232.     // calc the drive number.  
  233.     pSCIP->irDriveRegs.bDriveHeadReg = 0xA0 | ( ( bDriveNum & 1 ) << 4 );  
  234.  
  235.     // The command can either be IDE identify or ATAPI identify.  
  236.     pSCIP->irDriveRegs.bCommandReg = bIDCmd;  
  237.     pSCIP->bDriveNumber = bDriveNum;  
  238.     pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;  
  239.       
  240.     return DeviceIoControl( hPhysicalDriveIOCTL, DFP_RECEIVE_DRIVE_DATA,  
  241.         ( LPVOID ) pSCIP,  
  242.         sizeof( SENDCMDINPARAMS ) - 1,  
  243.         ( LPVOID ) pSCOP,  
  244.         sizeof( SENDCMDOUTPARAMS ) + IDENTIFY_BUFFER_SIZE - 1,  
  245.         lpcbBytesReturned, NULL );  
  246. }  
  247.  
  248. BOOL WinNTHDSerialNumAsPhysicalRead( BYTE* dwSerial, UINT* puSerialLen, UINT uMaxSerialLen )  
  249. {  
  250. #define  DFP_GET_VERSION          0x00074080  
  251.     BOOL bInfoLoaded = FALSE;  
  252.  
  253.     for( UINT uDrive = 0; uDrive < 4; ++ uDrive )  
  254.     {  
  255.         HANDLE hPhysicalDriveIOCTL = 0;  
  256.  
  257.         //  Try to get a handle to PhysicalDrive IOCTL, report failure  
  258.         //  and exit if can't.   
  259.         char szDriveName [256];   
  260.         sprintf( szDriveName, "\\\\.\\PhysicalDrive%d", uDrive );   
  261.   
  262.         //  Windows NT, Windows 2000, must have admin rights   
  263.         hPhysicalDriveIOCTL = CreateFile( szDriveName,   
  264.             GENERIC_READ | GENERIC_WRITE,    
  265.             FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,   
  266.             OPEN_EXISTING, 0, NULL);   
  267.   
  268.         if( hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE )   
  269.         {   
  270.             GETVERSIONOUTPARAMS VersionParams = { 0 };   
  271.             DWORD               cbBytesReturned = 0;   
  272.   
  273.             // Get the version, etc of PhysicalDrive IOCTL   
  274.             if( DeviceIoControl( hPhysicalDriveIOCTL, DFP_GET_VERSION,   
  275.                 NULL,    
  276.                 0,   
  277.                 &VersionParams,   
  278.                 sizeof( GETVERSIONOUTPARAMS ),   
  279.                 &cbBytesReturned, NULL ) )   
  280.             {   
  281.                 // If there is a IDE device at number "i" issue commands   
  282.                 // to the device   
  283.                 if( VersionParams.bIDEDeviceMap != 0 )   
  284.                 {   
  285.                     BYTE             bIDCmd = 0;   // IDE or ATAPI IDENTIFY cmd   
  286.                     SENDCMDINPARAMS  scip = { 0 };   
  287.   
  288.                     // Now, get the ID sector for all IDE devices in the system.   
  289.                     // If the device is ATAPI use the IDE_ATAPI_IDENTIFY command,   
  290.                     // otherwise use the IDE_ATA_IDENTIFY command   
  291.                     bIDCmd = ( VersionParams.bIDEDeviceMap >> uDrive & 0x10 ) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;   
  292.                     BYTE IdOutCmd[sizeof( SENDCMDOUTPARAMS ) + IDENTIFY_BUFFER_SIZE - 1] = { 0 };   
  293.   
  294.                     if( DoIdentify( hPhysicalDriveIOCTL,    
  295.                         &scip,    
  296.                         ( PSENDCMDOUTPARAMS )&IdOutCmd,    
  297.                         ( BYTE )bIDCmd,   
  298.                         ( BYTE )uDrive,   
  299.                         &cbBytesReturned ) )   
  300.                     {   
  301.                         if( * puSerialLen + 20U <= uMaxSerialLen )   
  302.                         {   
  303.                             CopyMemory( dwSerial + * puSerialLen, ( ( USHORT* )( ( ( PSENDCMDOUTPARAMS )IdOutCmd )->bBuffer ) ) + 10, 20 );  // 序列号   
  304.   
  305.                             // Cut off the trailing blanks   
  306.                             forUINT i = 20; i != 0U && ' ' == dwSerial[* puSerialLen + i - 1]; -- i )  {}   
  307.                             * puSerialLen += i;   
  308.   
  309.                             CopyMemory( dwSerial + * puSerialLen, ( ( USHORT* )( ( ( PSENDCMDOUTPARAMS )IdOutCmd )->bBuffer ) ) + 27, 40 ); // 型号   
  310.   
  311.                             // Cut off the trailing blanks   
  312.                             for( i = 40; i != 0U && ' ' == dwSerial[* puSerialLen + i - 1]; -- i )  {}   
  313.                             * puSerialLen += i;   
  314.   
  315.                             bInfoLoaded = TRUE;   
  316.                         }   
  317.                         else  
  318.                         {   
  319.                             ::CloseHandle( hPhysicalDriveIOCTL );   
  320.                             return bInfoLoaded;   
  321.                         }   
  322.                     }   
  323.                 }   
  324.             }   
  325.             CloseHandle( hPhysicalDriveIOCTL );   
  326.         }   
  327.     }   
  328.     return bInfoLoaded;   
  329. }   
  330.   
  331. UINT FindAwardBios( BYTE** ppBiosAddr )   
  332. {   
  333.     BYTE* pBiosAddr = * ppBiosAddr + 0xEC71;   
  334.   
  335.     BYTE szBiosData[128];   
  336.     CopyMemory( szBiosData, pBiosAddr, 127 );   
  337.     szBiosData[127] = 0;   
  338.        
  339.     int iLen = lstrlen( ( char* )szBiosData );   
  340.     if( iLen > 0 && iLen < 128 )   
  341.     {   
  342.         //AWard:         07/08/2002-i845G-ITE8712-JF69VD0CC-00    
  343.         //Phoenix-Award: 03/12/2002-sis645-p4s333   
  344.         if( szBiosData[2] == '/' && szBiosData[5] == '/' )   
  345.         {   
  346.             BYTE* p = szBiosData;   
  347.             while( * p )   
  348.             {   
  349.                 if( * p < ' ' || * p >= 127 )   
  350.                 {   
  351.                     break;   
  352.                 }   
  353.                 ++ p;   
  354.             }   
  355.             if( * p == 0 )   
  356.             {   
  357.                 * ppBiosAddr = pBiosAddr;   
  358.                 return ( UINT )iLen;   
  359.             }   
  360.         }   
  361.     }   
  362.     return 0;   
  363. }   
  364.   
  365. UINT FindAmiBios( BYTE** ppBiosAddr )   
  366. {   
  367.     BYTE* pBiosAddr = * ppBiosAddr + 0xF478;   
  368.        
  369.     BYTE szBiosData[128];   
  370.     CopyMemory( szBiosData, pBiosAddr, 127 );   
  371.     szBiosData[127] = 0;   
  372.        
  373.     int iLen = lstrlen( ( char* )szBiosData );   
  374.     if( iLen > 0 && iLen < 128 )   
  375.     {   
  376.         // Example: "AMI: 51-2300-000000-00101111-030199-"   
  377.         if( szBiosData[2] == '-' && szBiosData[7] == '-' )   
  378.         {   
  379.             BYTE* p = szBiosData;   
  380.             while( * p )   
  381.             {   
  382.                 if( * p < ' ' || * p >= 127 )   
  383.                 {   
  384.                     break;   
  385.                 }   
  386.                 ++ p;   
  387.             }   
  388.             if( * p == 0 )   
  389.             {   
  390.                 * ppBiosAddr = pBiosAddr;   
  391.                 return ( UINT )iLen;   
  392.             }   
  393.         }   
  394.     }   
  395.     return 0;   
  396. }   
  397.   
  398. UINT FindPhoenixBios( BYTE** ppBiosAddr )   
  399. {   
  400.     UINT uOffset[3] = { 0x6577, 0x7196, 0x7550 };   
  401.     forUINT i = 0; i < 3; ++ i )   
  402.     {   
  403.         BYTE* pBiosAddr = * ppBiosAddr + uOffset[i];   
  404.   
  405.         BYTE szBiosData[128];   
  406.         CopyMemory( szBiosData, pBiosAddr, 127 );   
  407.         szBiosData[127] = 0;   
  408.   
  409.         int iLen = lstrlen( ( char* )szBiosData );   
  410.         if( iLen > 0 && iLen < 128 )   
  411.         {   
  412.             // Example: Phoenix "NITELT0.86B.0044.P11.9910111055"   
  413.             if( szBiosData[7] == '.' && szBiosData[11] == '.' )   
  414.             {   
  415.                 BYTE* p = szBiosData;   
  416.                 while( * p )   
  417.                 {   
  418.                     if( * p < ' ' || * p >= 127 )   
  419.                     {   
  420.                         break;   
  421.                     }   
  422.                     ++ p;   
  423.                 }   
  424.                 if( * p == 0 )   
  425.                 {   
  426.                     * ppBiosAddr = pBiosAddr;   
  427.                     return ( UINT )iLen;   
  428.                 }   
  429.             }   
  430.         }   
  431.     }   
  432.     return 0;   
  433. }   
  434.   


 

上一篇:返回列表

下一篇:VC重启计算机方法

文章信息

发布时间:2010-09-05

发布者:aquwcw

浏览次数: