C++获取硬盘序列号
作者自己已经在vs2008下编译通过,此代码获取的是机器的硬盘物理序列号(唯一的,即使格式化硬盘也不变)
main.cpp
#include "GetHDSerial.h"
#include <iostream>
#include <sstream>
#include <stdio.h>
using namespace std;
int main(int argc,char** argv){
CGetHDSerial* disk = new CGetHDSerial;
char *diskNumber=disk->GetHDSerial();//获取硬盘序列号
std::cout<<diskNumber<<std::endl;
return 0;
}
GetHDSerial.h
// GetHDSerial.h: interface for the CGetHDSerial class.
// Download by wxing/
//////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <stdio.h>
#define  SENDIDLENGTH  sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE
#define  IDENTIFY_BUFFER_SIZE  512
#define  FILE_DEVICE_SCSI              0x0000001b
#define  IOCTL_SCSI_MINIPORT_IDENTIFY  ((FILE_DEVICE_SCSI << 16) + 0x0501)
#define  IOCTL_SCSI_MINIPORT 0x0004D008  //  see NTDDSCSI.H for definition
#define  IDE_ATAPI_IDENTIFY  0xA1  //  Returns ID sector for ATAPI.
#define  IDE_ATA_IDENTIFY    0xEC  //  Returns ID sector for ATA.
#define  IOCTL_GET_DRIVE_INFO  0x0007c088
#define  IOCTL_GET_VERSION          0x00074080
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 _SRB_IO_CONTROL
{
    ULONG HeaderLength;
    UCHAR Signature[8];
    ULONG Timeout;
    ULONG ControlCode;
    ULONG ReturnCode;
    ULONG Length;
}SRB_IO_CONTROL, *PSRB_IO_CONTROL;
typedef struct _GETVERSIONOUTPARAMS
{
    BYTE bVersion;      // Binary driver version.
    BYTE bRevision;    // Binary driver revision.
    BYTE bReserved;    // Not used.
    BYTE bIDEDeviceMap; // Bit map of IDE devices.
    DWORD fCapabilities; // Bit mask of driver capabilities.
    DWORD dwReserved[4]; // For future use.
} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;
// 获取硬盘序列号的类
class CGetHDSerial 
{
public:
    CGetHDSerial();
    virtual ~CGetHDSerial();
    void  _stdcall Win9xReadHDSerial(WORD * buffer);
    char* GetHDSerial();
    char* WORDToChar (WORD diskdata [256], int firstIndex, int lastIndex);
    char* DWORDToChar (DWORD diskdata [256], int firstIndex, int lastIndex);
    BOOL  WinNTReadSCSIHDSerial(DWORD * buffer);
    BOOL  WinNTReadIDEHDSerial (DWORD * buffer);
    BOOL  WinNTGetIDEHDInfo (HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,
        PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum,
        PDWORD lpcbBytesReturned);
};
GetHDSerial.cpp
#include "GetHDSerial.h"
char  m_buffer[256];
WORD  m_serial[256];
DWORD m_OldInterruptAddress;
DWORDLONG m_IDTR;
// 等待硬盘空闲
static unsigned int WaitHardDiskIdle() 
硬盘序列号查询
BYTE byTemp;
Waiting:
_asm
{
mov dx, 0x1f7
in al, dx
cmp al, 0x80
jb Endwaiting
jmp Waiting
}
Endwaiting:
_asm
{
mov byTemp, al
}
return byTemp; 
//中断服务程序
void  _declspec( naked )InterruptProcess(void)
{
int   byTemp;
int   i;
WORD temp;
//保存寄存器值
_asm
{
push eax
push ebx
push ecx
push edx
push esi
}
WaitHardDiskIdle();//等待硬盘空闲状态
_asm
{
mov dx, 0x1f6
mov al, 0xa0
out dx, al
}
byTemp = WaitHardDiskIdle(); //若直接在Ring3级执行等待命令,会进入死循环
if ((byTemp&0x50)!=0x50) 
{
_asm  // 恢复中断现场并退出中断服务程序
{
pop esi
pop edx
pop ecx
pop ebx
pop eax
iretd
}
}
_asm
{
mov dx, 0x1f6 //命令端口1f6,选择驱动器0
mov al, 0xa0
out dx, al
inc dx
mov al, 0xec
out dx, al //发送读驱动器参数命令
}
byTemp = WaitHardDiskIdle(); 
if ((byTemp&0x58)!=0x58) 
{
_asm  // 恢复中断现场并退出中断服务程序
{
pop esi
pop edx
pop ecx
pop ebx
pop eax
iretd
}
}
//读取硬盘控制器的全部信息
for (i=0;i<256;i++) 
{
_asm
{
mov dx, 0x1f0
in ax, dx
mov temp, ax
}
m_serial[i] = temp; 
}                               
_asm
{
pop esi
pop edx
pop ecx
pop ebx
pop eax
iretd
}
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。