用硬盘物理编号(序列号)、mac地址、文件版本、当前时间来生成机器序列号

本文主要是介绍用硬盘物理编号(序列号)、mac地址、文件版本、当前时间来生成机器序列号,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载与http://www.xdty.org/1692

在制作程序注册机的时候需要获取到机器的唯一编号,本文从硬盘、网卡硬件地址及文件版本生成一个4*7的序列号,形如 3CEA-82E6-1396-9C78-45C4-06C9-9564

1.获取硬盘物理地址(非逻辑分区序列号)
逻辑分区序列号获取很简单,但是这个编号不唯一,且可以轻易修改。如果ghost系统的话恐怕id也一样,所以获取硬盘的物理地址更合理一些。
需要的结构体及头文件

#include <winioctl.h>

#include <pshpack1.h>
#pragma pack(1)

typedef struct _IDENTIFY_DATA {
    USHORT GeneralConfiguration ;             // 00 00
    USHORT NumberOfCylinders ;               // 02  1
    USHORT Reserved1 ;                       // 04  2
    USHORT NumberOfHeads ;                   // 06  3
    USHORT UnformattedBytesPerTrack ;         // 08  4
    USHORT UnformattedBytesPerSector ;       // 0A  5
    USHORT SectorsPerTrack ;                 // 0C  6
    USHORT VendorUnique1 [ 3 ] ;                 // 0E  7-9
    USHORT SerialNumber [ 10 ] ;                 // 14  10-19
    USHORT BufferType ;                       // 28  20
    USHORT BufferSectorSize ;                 // 2A  21
    USHORT NumberOfEccBytes ;                 // 2C  22
    USHORT FirmwareRevision [ 4 ] ;             // 2E  23-26
    USHORT ModelNumber [ 20 ] ;                 // 36  27-46
    UCHAR  MaximumBlockTransfer ;             // 5E  47
    UCHAR  VendorUnique2 ;                   // 5F
    USHORT DoubleWordIo ;                     // 60  48
    USHORT Capabilities ;                     // 62  49
    USHORT Reserved2 ;                       // 64  50
    UCHAR  VendorUnique3 ;                   // 66  51
    UCHAR  PioCycleTimingMode ;               // 67
    UCHAR  VendorUnique4 ;                   // 68  52
    UCHAR  DmaCycleTimingMode ;               // 69
    USHORT TranslationFieldsValid : 1 ;         // 6A  53
    USHORT Reserved3 : 15 ;
    USHORT NumberOfCurrentCylinders ;         // 6C  54
    USHORT NumberOfCurrentHeads ;             // 6E  55
    USHORT CurrentSectorsPerTrack ;           // 70  56
    ULONG  CurrentSectorCapacity ;           // 72  57-58
    USHORT CurrentMultiSectorSetting ;       //     59
    ULONG  UserAddressableSectors ;           //     60-61
    USHORT SingleWordDMASupport : 8 ;         //     62
    USHORT SingleWordDMAActive : 8 ;
    USHORT MultiWordDMASupport : 8 ;         //     63
    USHORT MultiWordDMAActive : 8 ;
    USHORT AdvancedPIOModes : 8 ;             //     64
    USHORT Reserved4 : 8 ;
    USHORT MinimumMWXferCycleTime ;           //     65
    USHORT RecommendedMWXferCycleTime ;       //     66
    USHORT MinimumPIOCycleTime ;             //     67
    USHORT MinimumPIOCycleTimeIORDY ;         //     68
    USHORT Reserved5 [ 2 ] ;                     //     69-70
    USHORT ReleaseTimeOverlapped ;           //     71
    USHORT ReleaseTimeServiceCommand ;       //     72
    USHORT MajorRevision ;                   //     73
    USHORT MinorRevision ;                   //     74
    USHORT Reserved6 [ 50 ] ;                   //     75-126
    USHORT SpecialFunctionsEnabled ;         //     127
    USHORT Reserved7 [ 128 ] ;                   //     128-255
} IDENTIFY_DATA, *PIDENTIFY_DATA ;

#pragma pack()

实现函数

CString GetHardDiskSerialNumber ( )
{
    CString strHardDiskSerialNumber ;

    HANDLE hDrive = 0 ;

    CString szDriveName = _T ( "\\\\.\\PhysicalDrive0" ) ;

    hDrive = CreateFile (szDriveName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ) ;
    if (hDrive ! = INVALID_HANDLE_VALUE )
    {
        DWORD cbBytesReturned = 0 ;

        GETVERSIONINPARAMS objVersionParams ;
        memset ( &objVersionParams, 0, sizeof (objVersionParams ) ) ;
        if (  DeviceIoControl (hDrive, SMART_GET_VERSION, NULL, 0, &objVersionParams, sizeof (GETVERSIONINPARAMS ), &cbBytesReturned, NULL ) )
        {        
            ULONG nCommandSize = sizeof (SENDCMDINPARAMS ) + IDENTIFY_BUFFER_SIZE ;
            PSENDCMDINPARAMS pSendCommands = (PSENDCMDINPARAMS ) malloc (nCommandSize ) ;

            pSendCommands - >irDriveRegs. bCommandReg = ID_CMD ;
            DWORD BytesReturned = 0 ;
            if (DeviceIoControl (hDrive, SMART_RCV_DRIVE_DATA, pSendCommands, sizeof (SENDCMDINPARAMS ), pSendCommands, nCommandSize, &BytesReturned, NULL ) )
            {
                WORD * pIdSector = (WORD * ) (PIDENTIFY_DATA ) ( (PSENDCMDOUTPARAMS ) pSendCommands ) - >bBuffer ;

                char szSerialNumber [ 100 ] = "" ;
                for ( int index = 10, position = 0 ; index <= 19 ; index ++ )
                {
                    szSerialNumber [position ] = ( char ) (pIdSector [index ] / 256 ) ;
                    position ++ ;

                    szSerialNumber [position ] = ( char ) (pIdSector [index ] % 256 ) ;
                    position ++ ;
                }

                strHardDiskSerialNumber = szSerialNumber ;
                strHardDiskSerialNumber. TrimLeft ( ) ;
                strHardDiskSerialNumber. TrimRight ( ) ;
            }

            CloseHandle (hDrive ) ;
            free (pSendCommands ) ;
            pSendCommands = NULL ;
        }
    }

    return strHardDiskSerialNumber ;
}

最后获取到的字串类似为 WD-WMAYUS743480 ,只需要取后八位就可以了。

CString GetHardDiskSerialID ( )
{
    CString serialId = GetHardDiskSerialNumber ( ) ;
    serialId. Remove ( '-' ) ;
    return serialId. Right ( 8 ) ;
}

2.获取以太网网卡地址

CString GetMacAddress ( bool format /*=false*/ )
{
    CString csMacAddress ;
    ULONG BufferLength = 0 ;
    BYTE * pBuffer = 0 ;
    if ( ERROR_BUFFER_OVERFLOW == GetAdaptersInfo ( 0, &BufferLength ) )
    {
        pBuffer = new BYTE [ BufferLength ] ;
    }

    PIP_ADAPTER_INFO pAdapterInfo =
        reinterpret_cast <PIP_ADAPTER_INFO > (pBuffer ) ;
    GetAdaptersInfo ( pAdapterInfo, &BufferLength ) ;

    while ( pAdapterInfo )
    {
        if (pAdapterInfo - >Type ==MIB_IF_TYPE_ETHERNET )
        {
            CString szFormat ;
            if (format )
            {
                szFormat = _T ( "%02x:%02x:%02x:%02x:%02x:%02x" ) ;
            }
            else
            {
                szFormat = _T ( "%02x%02x%02x%02x%02x%02x" ) ;
            }
            csMacAddress. Format (szFormat,
                pAdapterInfo - >Address [ 0 ],
                pAdapterInfo - >Address [ 1 ],
                pAdapterInfo - >Address [ 2 ],
                pAdapterInfo - >Address [ 3 ],
                pAdapterInfo - >Address [ 4 ],
                pAdapterInfo - >Address [ 5 ] ) ;
        }
        pAdapterInfo = pAdapterInfo - >Next ;
    }
    delete [ ] pBuffer ;

    return csMacAddress ;
}

3.获取程序版本号
需要在项目属性连接里引入Version.lib

bool GetProductAndVersion (CString &strProductName, CString &strProductVersion )
{
    TCHAR szFilename [MAX_PATH + 1 ] = { 0 } ;
    if (GetModuleFileName ( NULL, szFilename, MAX_PATH ) == 0 )
    {
        return false ;
    }

    DWORD dummy ;
    DWORD dwSize = GetFileVersionInfoSize (szFilename, &dummy ) ;
    if (dwSize == 0 )
    {
        return false ;
    }
    std :: vector <BYTE > data (dwSize ) ;

    if ( !GetFileVersionInfo (szFilename, NULL, dwSize, &data [ 0 ] ) )
    {
        return false ;
    }

    LPVOID pvProductName = NULL ;
    unsigned int iProductNameLen = 0 ;
    LPVOID pvProductVersion = NULL ;
    unsigned int iProductVersionLen = 0 ;

    if ( !VerQueryValue ( &data [ 0 ], _T ( "\\StringFileInfo\\080404b0\\ProductName" ), &pvProductName, &iProductNameLen ) ||
        !VerQueryValue ( &data [ 0 ], _T ( "\\StringFileInfo\\080404b0\\ProductVersion" ), &pvProductVersion, &iProductVersionLen ) )
    {
        return false ;
    }

    strProductName. SetString ( (LPCTSTR )pvProductName, iProductNameLen ) ;
    strProductVersion. SetString ( (LPCTSTR )pvProductVersion, iProductVersionLen ) ;

    return true ;
}

CString GetFileVersion ( )
{
    CString strProductName, strProductVersion ;
    GetProductAndVersion (strProductName, strProductVersion ) ;

    return strProductVersion. Left (strProductVersion. ReverseFind ( '.' ) ) ;
}

4.生成序列号

CString CKeyController :: GenerateMachineID ( )
{
    CString serialID = GetHardDiskSerialID ( ) ;
    CString timeID ;
    timeID. Format (_T ( "%lx" ), time ( NULL ) ) ;
    timeID. Delete ( 6, 3 ) ;
    return serialID +timeID +GetMacAddress ( ) ;
}

CString CKeyController :: GenerateSerialNumber ( )
{
    CString serialNumber = GenerateMachineID ( ) ;
    for ( int i = 0 ; i < 6 ; i ++ )
    {
        serialNumber. Insert (i * 5 + 4, _T ( "-" ) ) ;
    }
    CString version = GetFileVersion ( ) ;
    version. Delete ( 1, 1 ) ;
    version. Delete ( 2, 1 ) ;
    version. Format (_T ( "%2x" ), _ttoi (version ) ) ;
    serialNumber. Append (version ) ;
    serialNumber. MakeUpper ( ) ;
    return serialNumber ;
}

最后调用GenerateSerialNumber()即可生成序列号。

这篇关于用硬盘物理编号(序列号)、mac地址、文件版本、当前时间来生成机器序列号的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1062096

相关文章

MybatisGenerator文件生成不出对应文件的问题

《MybatisGenerator文件生成不出对应文件的问题》本文介绍了使用MybatisGenerator生成文件时遇到的问题及解决方法,主要步骤包括检查目标表是否存在、是否能连接到数据库、配置生成... 目录MyBATisGenerator 文件生成不出对应文件先在项目结构里引入“targetProje

IDEA如何切换数据库版本mysql5或mysql8

《IDEA如何切换数据库版本mysql5或mysql8》本文介绍了如何将IntelliJIDEA从MySQL5切换到MySQL8的详细步骤,包括下载MySQL8、安装、配置、停止旧服务、启动新服务以及... 目录问题描述解决方案第一步第二步第三步第四步第五步总结问题描述最近想开发一个新应用,想使用mysq

java脚本使用不同版本jdk的说明介绍

《java脚本使用不同版本jdk的说明介绍》本文介绍了在Java中执行JavaScript脚本的几种方式,包括使用ScriptEngine、Nashorn和GraalVM,ScriptEngine适用... 目录Java脚本使用不同版本jdk的说明1.使用ScriptEngine执行javascript2.

mac中资源库在哪? macOS资源库文件夹详解

《mac中资源库在哪?macOS资源库文件夹详解》经常使用Mac电脑的用户会发现,找不到Mac电脑的资源库,我们怎么打开资源库并使用呢?下面我们就来看看macOS资源库文件夹详解... 在 MACOS 系统中,「资源库」文件夹是用来存放操作系统和 App 设置的核心位置。虽然平时我们很少直接跟它打交道,但了

Python使用qrcode库实现生成二维码的操作指南

《Python使用qrcode库实现生成二维码的操作指南》二维码是一种广泛使用的二维条码,因其高效的数据存储能力和易于扫描的特点,广泛应用于支付、身份验证、营销推广等领域,Pythonqrcode库是... 目录一、安装 python qrcode 库二、基本使用方法1. 生成简单二维码2. 生成带 Log

Debian如何查看系统版本? 7种轻松查看Debian版本信息的实用方法

《Debian如何查看系统版本?7种轻松查看Debian版本信息的实用方法》Debian是一个广泛使用的Linux发行版,用户有时需要查看其版本信息以进行系统管理、故障排除或兼容性检查,在Debia... 作为最受欢迎的 linux 发行版之一,Debian 的版本信息在日常使用和系统维护中起着至关重要的作

macOS怎么轻松更换App图标? Mac电脑图标更换指南

《macOS怎么轻松更换App图标?Mac电脑图标更换指南》想要给你的Mac电脑按照自己的喜好来更换App图标?其实非常简单,只需要两步就能搞定,下面我来详细讲解一下... 虽然 MACOS 的个性化定制选项已经「缩水」,不如早期版本那么丰富,www.chinasem.cn但我们仍然可以按照自己的喜好来更换

Python 标准库time时间的访问和转换问题小结

《Python标准库time时间的访问和转换问题小结》time模块为Python提供了处理时间和日期的多种功能,适用于多种与时间相关的场景,包括获取当前时间、格式化时间、暂停程序执行、计算程序运行时... 目录模块介绍使用场景主要类主要函数 - time()- sleep()- localtime()- g

Python使用Pandas库将Excel数据叠加生成新DataFrame的操作指南

《Python使用Pandas库将Excel数据叠加生成新DataFrame的操作指南》在日常数据处理工作中,我们经常需要将不同Excel文档中的数据整合到一个新的DataFrame中,以便进行进一步... 目录一、准备工作二、读取Excel文件三、数据叠加四、处理重复数据(可选)五、保存新DataFram

SpringBoot生成和操作PDF的代码详解

《SpringBoot生成和操作PDF的代码详解》本文主要介绍了在SpringBoot项目下,通过代码和操作步骤,详细的介绍了如何操作PDF,希望可以帮助到准备通过JAVA操作PDF的你,项目框架用的... 目录本文简介PDF文件简介代码实现PDF操作基于PDF模板生成,并下载完全基于代码生成,并保存合并P