//取得 cpu 的序列号的 WIN 32 API 函数,最好有例子

hzhxxx 2002-08-30 11:26:48
//取得 cpu 的序列号的 WIN 32 API 函数,最好有例子


小弟准备从 PB 转向 BCB ,请各位多多关照!
...全文
134 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
hzhxxx 2002-09-04
  • 打赏
  • 举报
回复
是不是 intel 的 CPU 才能啊,

其他 AMD,... 的是不可以,是吗?


谢谢关注!!!
hubao 2002-09-03
  • 打赏
  • 举报
回复
收藏!!
NowCan 2002-09-03
  • 打赏
  • 举报
回复
http://vip.6to23.com/NowCan1/tech/cpuid.htm
uio45757 2002-09-03
  • 打赏
  • 举报
回复
收藏!!
srm2000 2002-09-03
  • 打赏
  • 举报
回复
dreamnyj(梦晰) 你说Borland bcb5不支持CPUID这条指令,我以前也遇到。
其实是没有设置:在工程属性中,有指令集的一页(Advanced compiler),将默认的80386改为Pentium 或 Pentium Pro
drivers 2002-09-03
  • 打赏
  • 举报
回复
gz
bcb_fans 2002-09-02
  • 打赏
  • 举报
回复
使用0xA20F代替CPUID指令,如下所示:

MOV EAX,1
DW 0xA20F
dreamnyj 2002-09-02
  • 打赏
  • 举报
回复
不过Borland bcb5不支持CPUID这条指令。
无法编译通过
stidio_zhougang 2002-09-02
  • 打赏
  • 举报
回复
没办法了,只有这样一种方法,MSDN上面有这样一个例程,也是这样实现的。
lingbin 2002-09-02
  • 打赏
  • 举报
回复
我有源代码,试试看:
//------CPUID Instruction Demo Program------------
#include < conio.h >
#include < iostream.h >
#pragma hdrstop
//------------------------------------------------

#pragma inline
#pragma argsused

int main(int argc, char **argv)
{
char OEMString[13];
int iEAXValue,iEBXValue,iECXValue,iEDXValue;

_asm {
mov eax,0
cpuid
mov DWORD PTR OEMString,ebx
mov DWORD PTR OEMString+4,edx
mov DWORD PTR OEMString+8,ecx
mov BYTE PTR OEMString+12,0
}

cout< < "This CPU ''s OEM String is:"< < OEMString< < endl;

_asm {
mov eax,1
cpuid
mov iEAXValue,eax
mov iEBXValue,ebx
mov iECXValue,ecx
mov iEDXValue,edx
}

if(iEDXValue&0x800000)
cout < < "This is MMX CPU"< < endl;
else
cout < < "None MMX Support."< < endl;

int iCPUFamily=(0xf00 & iEAXValue) > >8;

cout < < "CPU Family is:"< < iCPUFamily< < endl;

_asm{
mov eax,2
CPUID
}

if(_AL==1)
cout < < "Pentium Pro or Pentium II Found";

getch();

return 0;

}
ysh 2002-09-02
  • 打赏
  • 举报
回复
为人为到底,送佛送到西!
其实上面的代码稍改一下就可以取得CPU序列号(如果有的话)
AnsiString GetCPUID(void)
{
int EAX_,EDX_,ECX_;
AnsiString CPUIDStr;
_asm
{
MOV EAX,01H
CPUID
MOV EAX_,EAX
MOV EDX_,EDX
}
if (EDX_ & 0x00000100)
{ //有序列号
_asm
{
MOV EAX,03H
CPUID
MOV EDX_,EDX
MOV ECX_,ECX
}
CPUIDStr=IntToHex(EAX_,8)+IntToHex(EDX_,8)+IntToHex(ECX_,8);
}
else
{
CPUIDStr="(NO CPU SERIALNO)";
}
return CPUIDStr;
}
ysh 2002-09-02
  • 打赏
  • 举报
回复
前几在CSDN找了一个,写出了下面的东东
typedef struct
{
AnsiString OEMString; //CPU厂商标识
AnsiString Type; //CPU型号
bool SupportMMX; //是否支持MMX指令指
bool IsPII; //是否是Pentium Pro 或者Pentium II以上版本的核心
}TCPUInfo;
/*---------------------------------------------------------------------------
void GetSystemCPUInfo(TCPUInfo *CPUInfo)
获取当前系统CPU的信息,调用此函数,要求使用Pentium兼容指令集编译
---------------------------------------------------------------------------*/
void GetSystemCPUInfo(TCPUInfo *CPUInfo)
{
char OEMString[13];
AnsiString TmpStr;
int iEAXValue,iEBXValue,iECXValue,iEDXValue;
memset(OEMString,0x0,13);
_asm
{
mov eax,0
CPUID
mov DWORD PTR OEMString,ebx
mov DWORD PTR OEMString+4,edx
mov DWORD PTR OEMString+8,ecx
mov BYTE PTR OEMString+12,0
}
CPUInfo->OEMString=String(OEMString);
_asm
{
mov eax,1
cpuid
mov iEAXValue,eax
mov iEBXValue,ebx
mov iECXValue,ecx
mov iEDXValue,edx
}
if(iEDXValue&0x800000)
CPUInfo->SupportMMX=true;
else
CPUInfo->SupportMMX=false;
int iCPUFamily=(0xf00 & iEAXValue) >>8;
switch(iCPUFamily)
{
case 3: CPUInfo->Type="80386"; break;
case 4: CPUInfo->Type="80486"; break;
case 5: CPUInfo->Type="Pentium"; break;
case 6: CPUInfo->Type="Pentium II"; break;
case 2: CPUInfo->Type="Dual Processors"; break;
case 15: CPUInfo->Type="Pentium 4"; break;
default: CPUInfo->Type="unknown(Family is "+IntToStr(iCPUFamily)+")";
}
_asm
{
mov eax,2
cpuid
}
if(_AL==1)
CPUInfo->IsPII=true;
else CPUInfo->IsPII=false;
}
至于取序列号,我记得网上也有现成的代码,找一下吧,实在不行,说声,我帮你找去。
pb_bulletsoft 2002-09-02
  • 打赏
  • 举报
回复
有没有一条API函数实现,取得CUP 序列号?
hzhxxx 2002-09-02
  • 打赏
  • 举报
回复
up
hzhxxx 2002-08-30
  • 打赏
  • 举报
回复
to 回复人: NowCan(能量、激情、雨水、彩虹——雷雨云) (

来点现实的! 代码!
NowCan 2002-08-30
  • 打赏
  • 举报
回复
hbxtx(xy) 是NT下进入ring0的方法,至于取CPU序列号,好像还不至于这样吧
dreamnyj 2002-08-30
  • 打赏
  • 举报
回复
GZ
I_Love_Soft 2002-08-30
  • 打赏
  • 举报
回复
标题:怎样用程序取得CPU信息

怎样用程序取得CPU信息


很 多 软 件 可 以 判 断所 运 行 的 电 脑 类 型 而 自 动 做 不 同 的
处 理。 如PhotoShop 5 可 以 探 测CPU 是 否 有MMX 支 持 而 调 用 不
同 的 处 理 函数,《 金 山 词 霸》 发 现 有MMX 支 持 会 产 生 半 透
明 的翻 译 提 示, 很 多 软 件 可 以 区 分Intel,Cyrix,AMD 的CPU...

现 在, 且 让 我 细 细道 来 如 何 让 你 在 自 己 的 程 序 中 取
得CPU 信 息。

主 要 可 利 用 利 用CPUID 汇 编 指 令( 机 器 码:0FH A2H, 如 果 你
的 编 译 器 不 支 持CPUID 指 令, 只 有emit 机 器 码 了) 该 指 令
可 以 被 如 下CPU 识别

Intel 486 以 上 的CPU,
Cyrix M1 以 上 的CPU,
AMD Am486 以 上 的CPU

(1) 取CPU OEM 字 符 串, 判 断CPU 厂商

先 让EAX=0, 再 调 用CPUID

Inel 的CPU 将 返 回:

EBX:756E6547H 'Genu'
EDX:49656E69H 'ineI'
ECX:6C65746EH 'ntel'
EBX,EDX,ECX 将 连 成"GenuineIntel", 真 正 的Intel。
Cyrix 的CPU 将 返 回:
EBX:43797269H
EDX:78496E73H
ECX:74656164H
"CyrixInstead","Cyrix 来 代 替"。
AMD 的CPU 将 返 回:
EBX:41757468H
EDX:656E7469H
ECX:63414D44H
"AuthenticAMD", 可 信 的AMD。

在Windows98 中, 用 右 键 单 击" 我 的 电 脑", 选 择" 属 性- 常 规"
在 计 算 机描 述 处 就 可 看 见CPU OEM 字 符 串。

(2)CPU 到 底 是 几86, 是 否 支 持MMX

先 让EAX=1, 再 调 用CPUID

EAX 的 8 到11 位 就 表 明 是 几86

3 - 386
4 - i486
5 - Pentium
6 - Pentium Pro Pentium II
2 - Dual Processors
EDX 的 第0 位: 有 无FPU

EDX 的 第23 位:CPU 是 否 支 持IA MMX, 很 重 要 啊 ! 如 果 你 想 用
那57 条 新 增 的 指 令, 先 检查 这 一 位 吧, 否 则 就 等 着 看Windows
的" 该 程 序 执行 了 非 法 指 令, 将 被 关 闭" 吧。

(3) 专 门 检 测 是 否P6 架 构

先 让EAX=1, 再 调 用CPUID

如 果AL=1, 就 是Pentium Pro 或Pentium II

(4) 专 门 检 测AMD 的CPU 信 息

先 让EAX=80000001H, 再 调 用CPUID

如 果EAX=51H, 是AMD K5

如 果EAX=66H, 是K6

K7 是 什 么 标 志, 只 有 等 大 家拿 到K7 的 芯 再 说 了。

EDX 第0 位: 是 否 有FPU( 多 余 的 !谁 用 过 没FPU 的K5,K6?)

EDX 第23 位,CPU 是 否 支 持MMX,

程 序 如 下: 是C++Builder 的 控 制台 程 序, 可 以 给 出 你 的" 心"
的 信 息。 如 果 把这 个 技 术 用 于DLL 中, 便 可 以 使VB 程 序
也 知 道" 心" 的 信 息。

//--CPUID Instruction Demo Program
#include

#include

#pragma hdrstop
//----
#pragma inline
#pragma argsused
int main(int argc, char **argv)
{
char OEMString[13];

int iEAXValue,iEBXValue,iECXValue,iEDXValue;
_asm {
mov eax,0
cpuid
mov DWORD PTR OEMString,ebx
mov DWORD PTR OEMString+4,edx
mov DWORD PTR OEMString+8,ecx
mov BYTE PTR OEMString+12,0
}

cout< < "This CPU 's OEM String is:"< < OEMString< < endl;

_asm {
mov eax,1
cpuid
mov iEAXValue,eax
mov iEBXValue,ebx
mov iECXValue,ecx
mov iEDXValue,edx
}

if(iEDXValue&0x800000)
cout < < "This is MMX CPU"< < endl;
else
cout < < "None MMX Support."< < endl;

int iCPUFamily=(0xf00 & iEAXValue) > >8;
cout < < "CPU Family is:"< < iCPUFamily< < endl;

_asm{
mov eax,2
CPUID
}
if(_AL==1)
cout < < "Pentium Pro or Pentium II Found";

getch();
return 0;
}
hbxtx 2002-08-30
  • 打赏
  • 举报
回复
别人的代码你试试:

extern "C" {
#include "ntddk.h"
}

#include <stdio.h>
#include <windows.h>
#include <aclapi.h>
#include <conio.h>

#define ENTERRING0 _asm pushad \
_asm pushf \
_asm cli

#define LEAVERING0 _asm popf \
_asm popad \
_asm retf

typedef struct gdtr {
unsigned short Limit;
unsigned short BaseLow;
unsigned short BaseHigh;
} Gdtr_t, *PGdtr_t;

typedef struct
{
unsigned short offset_0_15;
unsigned short selector;

unsigned char param_count : 4;
unsigned char some_bits : 4;

unsigned char type : 4;
unsigned char app_system : 1;
unsigned char dpl : 2;
unsigned char present : 1;

unsigned short offset_16_31;
} CALLGATE_DESCRIPTOR;



void PrintWin32Error( DWORD ErrorCode )
{
LPVOID lpMsgBuf;

FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, ErrorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf, 0, NULL );
printf("%s\n", lpMsgBuf );
LocalFree( lpMsgBuf );
}

ULONG MiniMmGetPhysicalAddress(ULONG virtualaddress)
{
if(virtualaddress<0x80000000||virtualaddress>=0xA0000000)
return 0;
return virtualaddress&0x1FFFF000;
}

VOID SetPhyscialMemorySectionCanBeWrited(HANDLE hSection)
{

PACL pDacl=NULL;
PACL pNewDacl=NULL;
PSECURITY_DESCRIPTOR pSD=NULL;
DWORD dwRes;
EXPLICIT_ACCESS ea;

if(dwRes=GetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,
NULL,NULL,&pDacl,NULL,&pSD)!=ERROR_SUCCESS)
{
printf( "GetSecurityInfo Error %u\n", dwRes );
goto CleanUp;
}

ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = SECTION_MAP_WRITE;
ea.grfAccessMode = GRANT_ACCESS;
ea.grfInheritance= NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
ea.Trustee.ptstrName = "CURRENT_USER";


if(dwRes=SetEntriesInAcl(1,&ea,pDacl,&pNewDacl)!=ERROR_SUCCESS)
{
printf( "SetEntriesInAcl %u\n", dwRes );
goto CleanUp;
}

if(dwRes=SetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,pNewDacl,NULL)!=ERROR_SUCCESS)
{
printf("SetSecurityInfo %u\n",dwRes);
goto CleanUp;
}

CleanUp:

if(pSD)
LocalFree(pSD);
if(pNewDacl)
LocalFree(pSD);
}

BOOL ExecRing0Proc(ULONG Entry,ULONG seglen)
{
Gdtr_t gdt;
__asm sgdt gdt;

ULONG mapAddr=MiniMmGetPhysicalAddress(gdt.BaseHigh<<16U|gdt.BaseLow);
if(!mapAddr) return 0;

HANDLE hSection=NULL;
NTSTATUS status;
OBJECT_ATTRIBUTES objectAttributes;
UNICODE_STRING objName;
CALLGATE_DESCRIPTOR *cg;

status = STATUS_SUCCESS;

RtlInitUnicodeString(&objName,L"\\Device\\PhysicalMemory");//这里是关键,可用ddk的obj

InitializeObjectAttributes(&objectAttributes,
&objName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
(PSECURITY_DESCRIPTOR) NULL);

status = ZwOpenSection(&hSection,SECTION_MAP_READ|SECTION_MAP_WRITE,&objectAttributes);

if(status == STATUS_ACCESS_DENIED){
status = ZwOpenSection(&hSection,READ_CONTROL|WRITE_DAC,&objectAttributes);
SetPhyscialMemorySectionCanBeWrited(hSection);
ZwClose(hSection);
status =ZwOpenSection(&hSection,SECTION_MAP_WRITE|SECTION_MAP_WRITE,&objectAttributes);
}

if(status != STATUS_SUCCESS)
{
printf("Error Open PhysicalMemory Section Object,Status:%08X\n",status);
return 0;
}

PVOID BaseAddress;

BaseAddress=MapViewOfFile(hSection,
FILE_MAP_READ|FILE_MAP_WRITE,
0,
mapAddr, //low part
(gdt.Limit+1));

if(!BaseAddress)
{
printf("Error MapViewOfFile:");
PrintWin32Error(GetLastError());
return 0;
}

BOOL setcg=FALSE;

for(cg=(CALLGATE_DESCRIPTOR *)((ULONG)BaseAddress+(gdt.Limit&0xFFF8));(ULONG)cg>(ULONG)BaseAddress;cg--)
if(cg->type == 0){
cg->offset_0_15 = LOWORD(Entry);
cg->selector = 8;
cg->param_count = 0;
cg->some_bits = 0;
cg->type = 0xC; // 386 call gate
cg->app_system = 0; // A system descriptor
cg->dpl = 3; // Ring 3 code can call
cg->present = 1;
cg->offset_16_31 = HIWORD(Entry);
setcg=TRUE;
break;
}

if(!setcg){
ZwClose(hSection);
return 0;
}

short farcall[3];

farcall[2]=((short)((ULONG)cg-(ULONG)BaseAddress))|3; //Ring 3 callgate;

if(!VirtualLock((PVOID)Entry,seglen))
{
printf("Error VirtualLock:");
PrintWin32Error(GetLastError());
return 0;
}

SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);

Sleep(0);

_asm call fword ptr [farcall]

SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL);

VirtualUnlock((PVOID)Entry,seglen);

//Clear callgate
*(ULONG *)cg=0;
*((ULONG *)cg+1)=0;

ZwClose(hSection);
return TRUE;

}

struct _RING0DATA
{
DWORD mcr0,mcr2,mcr3;
unsigned short BaseMemory;
unsigned short ExtendedMemory;
}r0Data;

void __declspec (naked) Ring0Proc1()
{
ENTERRING0;
_asm {
mov eax, cr0
mov r0Data.mcr0, eax;
mov eax, cr2
mov r0Data.mcr2, eax;
mov eax, cr3
mov r0Data.mcr3, eax;
}
LEAVERING0;
}

void __declspec (naked) Ring0Proc2()
{
ENTERRING0;
outp( 0x70, 0x15 );

_asm
{
mov ax,0
in al,71h
mov r0Data.BaseMemory,ax
}

outp( 0x70, 0x16 );
r0Data.BaseMemory += inp(0x71) << 8;
outp( 0x70, 0x17 );
r0Data.ExtendedMemory = inp( 0x71 );
outp( 0x70, 0x18 );
r0Data.ExtendedMemory += inp(0x71) << 8;
LEAVERING0;
}

void main(void)
{
ZeroMemory(&r0Data,sizeof(struct _RING0DATA));
VirtualLock((PVOID)&r0Data,sizeof(struct _RING0DATA));
ExecRing0Proc((ULONG)Ring0Proc1,0x100);
ExecRing0Proc((ULONG)Ring0Proc2,0x100);
VirtualUnlock((PVOID)&r0Data,sizeof(struct _RING0DATA));
printf("CR0 = %x\n", r0Data.mcr0);
printf("CR2 = %x\n", r0Data.mcr2);
printf("CR3 = %x\n", r0Data.mcr3);
printf("Base memory = %dK\n", r0Data.BaseMemory);
printf("Extended memory = %dK\n", r0Data.ExtendedMemory);
}
coolpony 2002-08-30
  • 打赏
  • 举报
回复
以前的帖子好像有,
你搜索一下啊。

1,220

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧