VC++ MFC如何获取CPU ID和硬盘序列号?
void CIntelCPUIDDlg::OnBtnCPUID()
{
无符号长整型s1,S2;
无符号字符vendor _ id[]= "-";//CPU提供程序id
CString str1,str2,str3
//下面是获取CPU ID的汇编语言指令。
_asm //获取CPU提供程序信息
{
Xor eax,eax //将eax清零。
Cpuid //获取Cpuid的指令
mov dword ptr供应商标识,ebx
mov双字指针供应商标识[+4],edx
mov双字指针供应商标识[+8],ecx
}
str1。格式(" %s ",vendor _ id);
_asm //获取CPU ID的高32位。
{
mov eax,01h
xor edx
cpuid
mov s2,eax
}
str2。格式(" %08X-",S2);
_asm //获取CPU ID的低64位。
{
mov eax,03h
xor ecx,ecx
xor edx
cpuid
mov s1,edx
mov s2,ecx
}
str3。格式(" %08X-%08X\n ",s1,S2);
str 2 = str 2+str 3;
m _编辑供应商。SetWindowText(str 1);
m_editCPUID。SetWindowText(str 2);
}
//gethdserial . CPP:CGetHDSerial类的实现。
//
//////////////////////////////////////////////////////////////////////
#包含" stdafx.h "
#包含" GetHDSerial.h "
char m _ buffer[256];
WORD m _ serial[256];
DWORD m _ OldInterruptAddress
德沃龙IDTR;
//等待硬盘空闲
静态无符号int WaitHardDiskIdle()
{
byTemp字节;
等待:
_asm
{
mov dx,0x1f7
在阿尔,dx
cmp al,0x80
jb结束等待
jmp等待
}
结束等待:
_asm
{
按温度移动
}
返回byTemp
}
//中断服务程序
void _declspec(裸)InterruptProcess(void)
{
int byTemp
int I;
WORD temp
//保存寄存器值
_asm
{
推送eax
推送ebx
推送ecx
推送edx
推送esi
}
waithardiskdidle();//等待硬盘空闲。
_asm
{
mov dx,0x1f6
0xa0的mov al
输出dx,al
}
byTemp = waitharddiskdidle();//如果直接在Ring3级别执行wait命令,会进入无限循环。
if((byTemp & amp;0x50)!=0x50)
{
_asm //恢复中断站点并退出中断服务程序。
{
pop esi
pop edx
pop ecx
pop ebx
pop eax
iretd
}
}
_asm
{
Mov dx,0x1f6 //命令端口1f6,选择驱动器0。
0xa0的mov al
输出dx,al
公司dx
mov al,0xec
Out dx,al //发送命令读取变频器参数。
}
byTemp = waitharddiskdidle();
if((byTemp & amp;0x58)!=0x58)
{
_asm //恢复中断站点并退出中断服务程序。
{
pop esi
pop edx
pop ecx
pop ebx
pop eax
iretd
}
}
//读取硬盘控制器的所有信息
for(I = 0;我& lt256;i++)
{
_asm
{
mov dx,0x1f0
在ax,dx
移动温度,ax
}
m _ serial[I]= temp;
}
_asm
{
pop esi
pop edx
pop ecx
pop ebx
pop eax
iretd
}
}
//////////////////////////////////////////////////////////////////////
//建设/破坏
//////////////////////////////////////////////////////////////////////
CGetHDSerial::CGetHDSerial()
{
}
CGetHDSerial::~CGetHDSerial()
{
}
//读取硬盘序列号功能
char* CGetHDSerial::GetHDSerial()
{
m _ buffer[0]= ' \ n ';
//获取当前操作系统版本
OS version info OS version info;
OSVERSIONINFO . dwosversioninfosize = sizeof(OSVERSIONINFO);
GetVersionEx(& amp;OS version info);
if (OSVersionInfo.dwPlatformId!= VER平台WIN32 NT)
{
//读取// Windows 9x/ME下的硬盘序列号。
WORD m _ wwin 9 xhdserial[256];
win 9 xreadhdserial(m _ wwin 9 xhdserial);
strcpy (m_buffer,WORDToChar (m_wWin9xHDSerial,10,19));
}
其他
{
//在Windows NT/2000/XP下读取硬盘序列号
DWORD m _ wWinNTHDSerial[256];
//确定是否有SCSI硬盘。
如果(!WinNTReadIDEHDSerial(m _ wWinNTHDSerial))
WinNTReadSCSIHDSerial(m _ wWinNTHDSerial);
strcpy (m_buffer,DWORDToChar (m_wWinNTHDSerial,10,19));
}
返回m _ buffer
}
//读取// Windows9X/ME系统下的硬盘序列号。
void _ stdcall CGetHDSerial::win 9 xreadhdserial(WORD * buffer)
{
int I;
for(I = 0;我& lt256;i++)
缓冲区[I]= 0;
_asm
{
推送eax
//获取被修改中断的中断描述符(中断门)地址。
西德IDTR
mov eax,dword ptr [m_IDTR+02h]
添加eax,3*08h+04h
硬币指示器 (coin-levelindicator的缩写)命令行界面(Command Line Interface for batch scripting)
//保存原始中断入口地址。
推送ecx
mov ecx,双字指针[eax]
mov cx,字ptr [eax-04h]
mov dword ptr m _ OldInterruptAddress,ecx
pop ecx
//将修改后的中断入口地址设置为新的中断处理程序入口地址。
推送ebx
lea ebx,中断流程
mov字ptr [eax-04h],bx
shr ebx,10h
mov字ptr [eax+02h],bx
pop ebx
//执行中断,转到Ring 0(类似CIH病毒的原理)
int 3h
//恢复原来的中断入口地址
推送ecx
mov ecx,dword ptr m_OldInterruptAddress
mov字ptr [eax-04h],cx
shr ecx,10h
mov字ptr [eax+02h],cx
pop ecx
标准工具清单(Standard Tool Inventories)
pop eax
}
for(I = 0;我& lt256;i++)
buffer[I]= m _ serial[I];
}
//在// Windows 9x/ME系统下,WORD类型的硬盘信息转换为字符类型(char)。
char * CGetHDSerial::WORDToChar(WORD disk data[256],int firstIndex,int lastIndex)
{
静态字符字符串[1024];
int index = 0;
int position = 0;
//将字数组diskdata的内容按照高字节先低字节后的顺序存储到字符串中。
for(index = first index;index & lt= lastIndexindex++)
{
//存储在字中的高位字节
string[position]=(char)(disk data[index]/256);
position++;
//存储在字中的低位字节
string[position]=(char)(diskdata[index]% 256);
position++;
}
//添加字符串结束标志
string[position]= ' \ 0 ';
//删除字符串中的空格
for(index = position-1;index & gt0 & amp& amp' = = string[index];索引-)
string[index]= ' \ 0 ';
返回字符串;
}
//在Windows NT/2000/XP系统下,双字类型(DWORD)的硬盘信息转换为字符类型(char)。
char * CGetHDSerial::DWORDToChar(DWORD disk data[256],int firstIndex,int lastIndex)
{
静态字符字符串[1024];
int index = 0;
int position = 0;
//按照高字节先低字节后的顺序,将双字中的低位字存储到字符串中。
for(index = first index;index & lt= lastIndexindex++)
{
//高位字节存储在低位字中
string[position]=(char)(disk data[index]/256);
position++;
//低位字中存储的低位字节
string[position]=(char)(diskdata[index]% 256);
position++;
}
//添加字符串结束标志
string[position]= ' \ 0 ';
//删除字符串中的空格
for(index = position-1;index & gt0 & amp& amp' = = string[index];索引-)
string[index]= ' \ 0 ';
返回字符串;
}
//在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];
句柄hpphysicaldriveioctl = 0;
sprintf (driveName," \\\\。\\PhysicalDrive%d ",drive);
//在Windows NT/2000/XP下创建文件需要管理员权限。
hpphysicaldriveioctl = create file(driveName,
泛型_READ |泛型_WRITE,
文件共享读取|文件共享写入,空,
OPEN_EXISTING,0,NULL);
if(hpphysicaldriveioctl!=无效句柄值)
{
getversionoputparams version params;
DWORD cbBytesReturned = 0;
//获取驱动器的IO控制器版本。
memset((void *)& amp;VersionParams,0,size of(version params));
if(device iocontrol(hpphysicaldriveioctl,IOCTL_GET_VERSION,
空值、0和。版本参数,
sizeof(版本参数),
& ampcbBytesReturned,NULL))
{
if(version params . bidevicemap & gt;0)
{
字节bid cmd = 0;// IDE或ATAPI识别命令
SENDCMDINPARAMS scip
//如果驱动器是光驱,请使用命令IDE_ATAPI_IDENTIFY,command,
//否则,使用命令IDE_ATA_IDENTIFY读取驱动器信息。
bid cmd =(version params . bidevicemap & gt;& gt驾驶与娱乐。0x10)?
IDE _ ATAPI _ IDENTIFY:IDE _ ATA _ IDENTIFY;
memset(& amp;scip,0,sizeof(scip));
memset (IdOutCmd,0,sizeof(IdOutCmd));
//获取驱动器信息
if(WinNTGetIDEHDInfo(hpphysicaldriveioctl,
& ampscip,
(PSENDCMDOUTPARAMS)IdOutCmd,
(字节)bIDCmd,
(字节)驱动器,
& ampcbBytesReturned))
{
int m = 0;
USHORT *pIdSector = (USHORT *)
((PSENDCMDOUTPARAMS)IdOutCmd)-& gt;bBuffer
for(m = 0;m & lt256;m++)
buffer[m]= PID sector[m];
bFlag = TRUE//读取硬盘信息成功。
}
}
}
close handle(hpphysicaldriveioctl);//关闭句柄
}
返回bFlag
}
//在Windows NT/2000/XP系统下读取SCSI硬盘序列号。
BOOL CGetHDSerial::WinNTReadSCSIHDSerial(DWORD * buffer)
{
buffer[0]= ' \ n ';
int controller = 0;
HANDLE hScsiDriveIOCTL = 0;
char driveName[256];
sprintf (driveName," \\\\。\\Scsi%d:",控制器);
//任何权限都可以在Windows NT/2000/XP下执行。
hScsiDriveIOCTL = create file(driveName,
泛型_READ |泛型_WRITE,
文件共享读取|文件共享写入,空,
OPEN_EXISTING,0,NULL);
if (hScsiDriveIOCTL!=无效句柄值)
{
int drive = 0;
DWORD dummy
for(drive = 0;驾驶& lt2;drive++)
{
char buffer[sizeof(SRB _ IO _ CONTROL)+sendilength];
SRB _ IO _ CONTROL * p =(SRB _ IO _ CONTROL *)缓冲区;
SENDCMDINPARAMS *pin =
(SENDCMDINPARAMS *)(buffer+sizeof(SRB _ IO _ CONTROL));
//准备参数
memset (buffer,0,sizeof (buffer))。
p->;header length = sizeof(SRB _ IO _ CONTROL);
p->;超时= 10000;
p->;Length = SENDIDLENGTH
p->;control code = IOCTL _ SCSI _ MINIPORT _ IDENTIFY;
strncpy((char *)p-& gt;签名,“SCSIDISK”,8);
pin->;irdriveregs . bcommandreg = IDE _ ATA _ IDENTIFY;
pin->;bDriveNumber = drive
//获取SCSI硬盘信息
if(device iocontrol(hScsiDriveIOCTL,IOCTL_SCSI_MINIPORT,
缓冲区,
sizeof (SRB_IO_CONTROL) +
sizeof(SENDCMDINPARAMS)-1,
缓冲区,
sizeof(SRB _ IO _ CONTROL)+sendilength,
& amp哑元,空值))
{
SENDCMDOUTPARAMS *pOut =
(SENDCMDOUTPARAMS *)(buffer+sizeof(SRB _ IO _ CONTROL));
id sector * pId =(id sector *)(pOut-& gt;bBuffer);
if(pId-& gt;sModelNumber [0])
{
int n = 0;
USHORT * pId sector =(USHORT *)pId;
for(n = 0;n & lt256;n++)
buffer[n]= PID sector[n];
返回TRUE//读取成功
}
}
}
close handle(hScsiDriveIOCTL);//关闭句柄
}
返回FALSE//读取失败
}
//在Windows NT/2000/XP下读取IDE设备信息
BOOL CGetHDSerial::WinNTGetIDEHDInfo(HANDLE hpphysicaldriveioctl,PSENDCMDINPARAMS pSCIP,
PSENDCMDOUTPARAMS pSCOP,字节bIDCmd,字节bDriveNum,
PDWORD lpcbBytesReturned)
{
//准备读取设备信息的参数
PSP CIP->;cBufferSize = IDENTIFY _ BUFFER _ SIZE;
PSP CIP->;irdriveregs . bfeaturesreg = 0;
PSP CIP->;irdriveregs . bsectorcountreg = 1;
PSP CIP->;irdriveregs . bsectornumberreg = 1;
PSP CIP->;irdriveregs . bcyllowreg = 0;
PSP CIP->;irdriveregs . bcylhighreg = 0;
//计算驱动器位置
PSP CIP->;irdriveregs . bdriveheadreg = 0xa 0 |((bDriveNum & amp;1)& lt;& lt4);
//设置读取命令
PSP CIP->;irdriveregs . bcommandreg = bid cmd;
PSP CIP->;bDriveNumber = bDriveNum
PSP CIP->;cBufferSize = IDENTIFY _ BUFFER _ SIZE;
//读取驱动器信息
return(device iocontrol(hpphysicaldriveioctl,IOCTL_GET_DRIVE_INFO,
(LPVOID) pSCIP,
sizeof(SENDCMDINPARAMS)-1,
(LPVOID) pSCOP,
sizeof(SENDCMDOUTPARAMS)+IDENTIFY _ BUFFER _ SIZE-1,
lpcbBytesReturned,NULL));
}