zoukankan      html  css  js  c++  java
  • <转>另一个获取硬盘序列号的方法

    原谅转自:http://blog.sina.com.cn/s/blog_57dff12f0100d5so.html

    #define  DFP_GET_VERSION                    0x00074080
    #define  FILE_DEVICE_SCSI                   0x0000001b
    #define  IOCTL_SCSI_MINIPORT_IDENTIFY       ((FILE_DEVICE_SCSI << 16 ) + 0x0501)
    #define  IOCTL_SCSI_MINIPORT                0x0004D008
    #define  IDENTIFY_BUFFER_SIZE               512
    #define  SENDIDLENGTH                       (sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE)
    #define  IDE_ATAPI_IDENTIFY                 0xA1
    #define  IDE_ATA_IDENTIFY                   0xEC
    #define  DFP_RECEIVE_DRIVE_DATA             0x0007c088

    typedef struct _IDSECTOR
    {
        USHORT  wGenConfig;
        USHORT  wNumCyls;
        USHORT  wReserved;
        USHORT  wNumHeads;
        USHORT  wBytesPerTrack;
        USHORT  wBytesPerSector;
        USHORT  wSectorsPerTrack;
        USHORT  wVendorUnique[3];
        CHAR    sSerialNumber[20];
        USHORT  wBufferType;
        USHORT  wBufferSize;
        USHORT  wECCSize;
        CHAR    sFirmwareRev[8];
        CHAR    sModelNumber[40];
        USHORT  wMoreVendorUnique;
        USHORT  wDoubleWordIO;
        USHORT  wCapabilities;
        USHORT  wReserved1;
        USHORT  wPIOTiming;
        USHORT  wDMATiming;
        USHORT  wBS;
        USHORT  wNumCurrentCyls;
        USHORT  wNumCurrentHeads;
        USHORT  wNumCurrentSectorsPerTrack;
        ULONG   ulCurrentSectorCapacity;
        USHORT  wMultSectorStuff;
        ULONG   ulTotalAddressableSectors;
        USHORT  wSingleWordDMA;
        USHORT  wMultiWordDMA;
        BYTE    bReserved[128];
    }IDSECTOR, *PIDSECTOR;

    //typedef struct _DRIVERSTATUS
    //{
    //    BYTE  bDriverError;
    //    BYTE  bIDEStatus;
    //    BYTE  bReserved[2];
    //    DWORD  dwReserved[2];
    //
    //}DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;

    //typedef struct _SENDCMDOUTPARAMS
    //{
    //    DWORD         cBufferSize;
    //    DRIVERSTATUS  DriverStatus;
    //    BYTE          bBuffer[1];
    //}SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;

    typedef struct _SRB_IO_CONTROL
    {
        ULONG HeaderLength;
        UCHAR Signature[8];
        ULONG Timeout;
        ULONG ControlCode;
        ULONG ReturnCode;
        ULONG Length;
    }SRB_IO_CONTROL, *PSRB_IO_CONTROL;

    //typedef struct _IDEREGS
    //{//
    //    BYTE bFeaturesReg;
    //    BYTE bSectorCountReg;
    //    BYTE bSectorNumberReg;
    //    BYTE bCylLowReg;
    //    BYTE bCylHighReg;
    //    BYTE bDriveHeadReg;
    //    BYTE bCommandReg;
    //    BYTE bReserved;
    //
    //}IDEREGS, *PIDEREGS, *LPIDEREGS;

    //typedef struct _SENDCMDINPARAMS
    //{
    //    DWORD     cBufferSize;
    //    IDEREGS   irDriveRegs;
    //    BYTE bDriveNumber;
    //    BYTE bReserved[3];
    //    DWORD     dwReserved[4];
    //    BYTE      bBuffer[1];
    //}SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;

    typedef struct _GETVERSIONOUTPARAMS
    {
        BYTE bVersion;
        BYTE bRevision;
        BYTE bReserved;
        BYTE bIDEDeviceMap;
        DWORD fCapabilities;
        DWORD dwReserved[4];

    }GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;

    typedef struct _UNICODE_STRING
    {
        USHORT  Length;
        USHORT  MaximumLength;
        PWSTR  Buffer;

    }UNICODE_STRING,*PUNICODE_STRING;

    typedef struct _OBJECT_ATTRIBUTES
    {
        ULONG Length;
        HANDLE RootDirectory;
        PUNICODE_STRING ObjectName;
        ULONG Attributes;
        PVOID SecurityDescriptor;
        PVOID SecurityQualityOfService;

    }OBJECT_ATTRIBUTES;

    typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;

    // 函数指针

    typedef DWORD  (__stdcall *ZWOS )( PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES);
    typedef DWORD  (__stdcall *ZWMV )( HANDLE,HANDLE,PVOID,ULONG,ULONG,PLARGE_INTEGER,PSIZE_T,DWORD,ULONG,ULONG);
    typedef DWORD  (__stdcall *ZWUMV )( HANDLE,PVOID);


    BOOL WinNTHDSerialNumAsScsiRead(BYTE* dwSerial, UINT* puSerialLen, UINT uMaxSerialLen)
    {
        BOOL bInfoLoaded = FALSE;

        for (int iController = 0; iController < 2; ++iController)
        {
            HANDLE hScsiDriveIOCTL = 0;
            char szDriveName[256];

            sprintf( szDriveName, "\\\\.\\Scsi%d:", iController );

            //  Windows NT, Windows 2000, any rights should do

            hScsiDriveIOCTL = CreateFile(szDriveName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

            // if (hScsiDriveIOCTL == INVALID_HANDLE_VALUE)
            //    printf ("Unable to open SCSI controller %d, error code: 0x%lX\n",
            //            controller, GetLastError ());

            if( hScsiDriveIOCTL != INVALID_HANDLE_VALUE )
            {
                int iDrive = 0;

                for (iDrive = 0; iDrive < 2; ++ iDrive)
                {
                    char szBuffer[sizeof (SRB_IO_CONTROL) + SENDIDLENGTH] = { 0 };
                    SRB_IO_CONTROL* p = ( SRB_IO_CONTROL* )szBuffer;
                    SENDCMDINPARAMS* pin = ( SENDCMDINPARAMS* )( szBuffer + sizeof (SRB_IO_CONTROL));
                    DWORD dwResult;

                    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 = iDrive;

                    if (DeviceIoControl(hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT, szBuffer, sizeof (SRB_IO_CONTROL) + sizeof (SENDCMDINPARAMS) - 1, szBuffer, sizeof (SRB_IO_CONTROL) + SENDIDLENGTH, &dwResult, NULL))
                    {
                        SENDCMDOUTPARAMS* pOut = (SENDCMDOUTPARAMS*) (szBuffer + sizeof( SRB_IO_CONTROL));
                        IDSECTOR* pId = (IDSECTOR*) (pOut->bBuffer);

                        if (pId->sModelNumber[0])
                        {
                            if (* puSerialLen + 20U <= uMaxSerialLen)
                            {
                                CopyMemory(dwSerial + * puSerialLen, ((USHORT*) pId) + 10, 20);

                                // Cut off the trailing blanks
                                for (UINT i = 20; i != 0U && ' ' == dwSerial[* puSerialLen + i - 1]; --i);

                                * puSerialLen += i;

                                CopyMemory( dwSerial + * puSerialLen, ( ( USHORT* )pId ) + 27, 40 );

                                // Cut off the trailing blanks
                                for( i = 40; i != 0U && ' ' == dwSerial[* puSerialLen + i - 1]; -- i );

                                * puSerialLen += i;

                                bInfoLoaded = TRUE;
                            }
                            else
                            {
                                ::CloseHandle( hScsiDriveIOCTL );
                                return bInfoLoaded;
                            }
                        }
                    }
                }
                ::CloseHandle( hScsiDriveIOCTL );
            }
        }
        return bInfoLoaded;
    }



    BOOL DoIdentify( HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP, PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum, PDWORD lpcbBytesReturned )
    {
        // Set up data structures for IDENTIFY command.

        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;

        // calc the drive number.

        pSCIP->irDriveRegs.bDriveHeadReg = 0xA0 | ( ( bDriveNum & 1 ) << 4 );

        // The command can either be IDE identify or ATAPI identify.

        pSCIP->irDriveRegs.bCommandReg = bIDCmd;
        pSCIP->bDriveNumber = bDriveNum;
        pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;

        return DeviceIoControl(hPhysicalDriveIOCTL, DFP_RECEIVE_DRIVE_DATA, (LPVOID) pSCIP, sizeof (SENDCMDINPARAMS) - 1, (LPVOID) pSCOP, sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1, lpcbBytesReturned, NULL);
    }


    BOOL WinNTHDSerialNumAsPhysicalRead( BYTE* dwSerial, UINT* puSerialLen, UINT uMaxSerialLen )
    {
        BOOL bInfoLoaded = FALSE;

        for (UINT uDrive = 0; uDrive < 4; ++ uDrive)
        {
            HANDLE hPhysicalDriveIOCTL = 0;

            //  Try to get a handle to PhysicalDrive IOCTL, report failure

            //  and exit if can't.

            char szDriveName [256];

            sprintf( szDriveName, "\\\\.\\PhysicalDrive%d", uDrive );

            //  Windows NT, Windows 2000, must have admin rights

            hPhysicalDriveIOCTL = CreateFile(szDriveName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

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

                // Get the version, etc of PhysicalDrive IOCTL

                if( DeviceIoControl( hPhysicalDriveIOCTL, DFP_GET_VERSION, NULL, 0, &VersionParams, sizeof (GETVERSIONOUTPARAMS), &cbBytesReturned, NULL))
                {
                    // If there is a IDE device at number "i" issue commands

                    // to the device

                    if (VersionParams.bIDEDeviceMap != 0)
                    {
                        BYTE             bIDCmd = 0;   // IDE or ATAPI IDENTIFY cmd
                        SENDCMDINPARAMS  scip = { 0 };

                        // Now, get the ID sector for all IDE devices in the system.

                        // If the device is ATAPI use the IDE_ATAPI_IDENTIFY command,

                        // otherwise use the IDE_ATA_IDENTIFY command

                        bIDCmd = (VersionParams.bIDEDeviceMap >> uDrive & 0x10) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;

                        BYTE IdOutCmd[sizeof( SENDCMDOUTPARAMS ) + IDENTIFY_BUFFER_SIZE - 1] = { 0 };

                        if (DoIdentify( hPhysicalDriveIOCTL, &scip, (PSENDCMDOUTPARAMS)&IdOutCmd, (BYTE)bIDCmd, (BYTE)uDrive, &cbBytesReturned))
                        {
                            if (* puSerialLen + 20U <= uMaxSerialLen)
                            {
                                CopyMemory(dwSerial + * puSerialLen, ((USHORT*)(((PSENDCMDOUTPARAMS )IdOutCmd )->bBuffer)) + 10, 20);  // 序列号

                                // Cut off the trailing blanks

                                for (UINT i = 20; i != 0U && ' ' == dwSerial[* puSerialLen + i - 1]; --i);

                                * puSerialLen += i;

                                CopyMemory(dwSerial + * puSerialLen, ((USHORT*)(((PSENDCMDOUTPARAMS)IdOutCmd )->bBuffer)) + 27, 40); // 型号

                                // Cut off the trailing blanks

                                for (i = 40; i != 0U && ' ' == dwSerial[* puSerialLen + i - 1]; -- i);

                                * puSerialLen += i;
                                bInfoLoaded = TRUE;
                            }
                            else
                            {
                                ::CloseHandle( hPhysicalDriveIOCTL );
                                return bInfoLoaded;
                            }
                        }
                    }
                }
                CloseHandle( hPhysicalDriveIOCTL );
            }
        }
        return bInfoLoaded;
    }

    // 如何获取硬盘序列好
    // 结果存放在 disk_info.txt 文件中
    void GetDiskSuquenceID()
    {
        UINT uSystemInfoLen;
        BYTE szSystemInfo[1024] = { 0 };
        OSVERSIONINFO ovi = { 0 };
        
        ovi.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
        GetVersionEx( &ovi );
       
        if( ovi.dwPlatformId != VER_PLATFORM_WIN32_NT )
            // 获取不到硬盘序列号信息,返回
            return;

        if( !WinNTHDSerialNumAsPhysicalRead(szSystemInfo, &uSystemInfoLen, 1024))
            WinNTHDSerialNumAsScsiRead(szSystemInfo, &uSystemInfoLen, 1024);
        // 以写追加的方式打开保存结果的文件
        FILE *pf = fopen("./disk_info.txt", "a+");

        // 检测文件指针的有效性

        assert(NULL != pf);
        if (NULL == pf)
            return;

        // 把硬盘序列号写入文件
        fprintf(pf, "\ndisk sequence info is %s\n",szSystemInfo );

        // 关闭文件
        fclose(pf);

    }

    本人新博客网址为:http://www.hizds.com
    本博客注有“转”字样的为转载文章,其余为本人原创文章,转载请务必注明出处或保存此段。c++/lua/windows逆向交流群:69148232
  • 相关阅读:
    数据库表结构查询SQL
    Java实现数据库备份并利用ant导入SQL脚本
    生死看淡,不服就干。SQL常见的一些优化。
    mybatis + PageHelper 实现分页
    自定义数据库连接池实现方式 MySQL
    Docker 镜像基础(三)
    Docker 镜像管理及基础命令(二)
    Docker 介绍和安装(一)
    Docker 镜像管理及基础命令(二)
    Tomcat-8 安装和配置
  • 原文地址:https://www.cnblogs.com/zhangdongsheng/p/3068221.html
Copyright © 2011-2022 走看看