用C语言怎么得到电脑的CPU序列号、硬盘序列号等信息。

yingyi8989 2006-11-10 09:16:16
用C语言怎么得到电脑的CPU序列号、硬盘序列号等信息。
请高手指点。
我要在LINUX中,用JAVA调用。
...全文
3953 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
left_zxp 2006-11-10
  • 打赏
  • 举报
回复
mark
thankall 2006-11-10
  • 打赏
  • 举报
回复
我靠,这么多。。。
飞哥 2006-11-10
  • 打赏
  • 举报
回复
取硬盘序列号可能有问题

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <asm/io.h>
#include <fcntl.h>
#include <linux/hdreg.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "crypt.h"

#define FALSE 0

typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef int BOOL;

static DWORD g_eax; // 存储返回的eax
static DWORD g_ebx; // 存储返回的ebx
static DWORD g_ecx; // 存储返回的ecx
static DWORD g_edx; // 存储返回的edx

//-------------------------------------------------------------------

void Executecpuid(DWORD veax)
{
asm("cpuid"
:"=a"(g_eax),
"=b"(g_ebx),
"=c"(g_ecx),
"=d"(g_edx)
:"a"(g_eax));
}

//------------------------------------------------------------------

int isSupport;
void GetSerialNumber(WORD nibble[6])
{
Executecpuid(1); // 执行cpuid,参数为 eax = 1
isSupport = g_edx & (1<<18); // edx是否为1代表CPU是否存在序列号
if (FALSE == isSupport) // 不支持,返回false
{
return ;
}
Executecpuid(3); // 执行cpuid,参数为 eax = 3
memcpy(&nibble[4], &g_eax, 4); // eax为最高位的两个WORD
memcpy(&nibble[0], &g_ecx, 8); // ecx 和 edx为低位的4个WORD

}

//-------------------------------------------------------------------
char str[31];
void ConvertSerial(WORD nibble[6])
{
int i; //序列号游标
int j = 0; //序列号段内游标
int k = 0; //字符串游标
char buffer[5]; //临时串

for ( i = 0; i < 6; i++)
{
sprintf(buffer,"%u",nibble[5-i]); //转换

while((j < strlen(buffer)))
{
str[k] = buffer[j];
k++;
j++;
}
j = 0;
}
str[k] = '\0';
}

//-------------------------------------------------------------------

void GetIDEPhysicalSerialNumber()
{
int ret;
int fd;
struct hd_driveid hdinfo;
fd = open("/dev/hda", O_NONBLOCK);
if (-1 == fd)
exit(-1);

ret = ioctl(fd, HDIO_GET_IDENTITY, (unsigned char*)&hdinfo);
if (-1 == ret)
exit(-1);

printf("IDE SN: %s\n", hdinfo.serial_no);

close(fd);
}

//-------------------------------------------------------------------
/* get serial number */
int gethddsn(char *ide)
{
unsigned int ide_info[257];
unsigned int info_off;
unsigned long loop2=0;
int loop, loop1=0;

if (ioperm(0x1f6, 1, 1)) {
perror("ioperm"); exit(-1);
}
outb(0xa0, 0x1f6);
if (ioperm(0x1f7, 1, 1)) {
perror("ioperm"); exit(-1);
}
outb(0xec, 0x1f7);
do {
if (ioperm(0x1f7, 1, 1)) {
perror("ioperm"); exit(-1);
}
} while (inb(0x1f7) != 0x58 && loop2++ < 0xffff);
for (info_off=0; info_off != 256; info_off++) {
if (ioperm(0x1f0, 2, 1)) {
perror("ioperm"); exit(-1);
}
ide_info[info_off] = inw(0x1f0);
}
for (loop=10, loop1=0; loop<=19; loop++)
{
ide[loop1++] = (char)(ide_info[loop] / 256);
ide[loop1++] = (char)(ide_info[loop] % 256);
}
ide[loop1] = 0;
if (loop1 > 40) printf("*error*\n");
return 0;
}
//---------------------------------------------------------------------
char *itostr ( int val, char *buf, int radix )
{
char *p = buf , *first, temp;
int digital;
if (val < 0)
{
*p++ = '-';
val = -val;
}
first = p;
do
{
digital = val%radix;
val /= radix;
if (digital > 9)
*p++ = (char)(digital - 10 + 'A');
else
*p++ = (char)(digital + '0');
}
while(val > 0);
*p-- = '\0';

do
{
temp = *p;
*p-- = *first;
*first++ = temp;
}
while(first < p);
return buf;
}
//-------------------------------------------------------------------

main()
{
WORD nibble[6];
unsigned char enc[30];
unsigned char dec[30];
char pwd[] ="Iloveit";

memset(enc,0,30);
memset(dec,0,30);
memset(str,0,31);

GetSerialNumber(nibble);//取序列号
ConvertSerial(nibble);//序列号转成字符串

EncryptByPwd(str,sizeof(str),pwd,enc);//加密字符串
printf("%s\n", enc);
DecryptByPwd(enc,sizeof(enc),pwd,dec);//解密字符串
printf("%s\n", dec);
}

hailongchang 2006-11-10
  • 打赏
  • 举报
回复
用CPUID指令,首先你可以确定你用的CPU是Intel的。然后执行:

MOV EAX,01H
CPUID

如果返回的EDX中,低18位为1,那么这个CPU就是支持序列号的。此时EAX就是序列号的高32位。这32位对同一型号的CPU是一样的。再执行:

MOV EAX,03H
CPUID

此时的EDX:ECX就是序列号的第64位。 要想关闭这个ID,可执行下列代码:

MOV ECX,119H
RDMSR
OR EAX,00200000H
WRMSR

不过,一旦执行上述代码,cpu 将一直不能取id,直到下次 reset。

// getcpuid.cpp : Defines the entry point for the console application.
//

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

int main(int argc, char* argv[])
{
unsigned long s1,s2;
unsigned char vendor_id[]="------------";
char sel;
printf("Select the function:\n1-------Read CPU id.\n2-------Disable CPU id.\n");
sel=getch();
switch(sel)
{
case '1':
_asm
{
xor eax,eax
cpuid
mov dword ptr vendor_id,ebx
mov dword ptr vendor_id[+4],edx
mov dword ptr vendor_id[+8],ecx
}
printf("%s-",vendor_id);
_asm
{
mov eax,01h
xor edx,edx
cpuid
mov s1,edx
mov s2,eax
}
printf("%08X\n%08X-",s1,s2);
_asm
{
mov eax,03h
xor ecx,ecx
xor edx,edx
cpuid
mov s1,edx
mov s2,ecx
}
printf("%08X-%08X\n",s1,s2);
break;
case '2':
_asm{
mov ecx,119h
rdmsr
or eax,00200000h
wrmsr
}
printf("CPU id is disabled.\n");
break;
}
return 0;
}

lz要把程序中的汇编代码改为AT&T格式的,在linux下才可以执行
飞哥 2006-11-10
  • 打赏
  • 举报
回复
获取CPU序列号要使用 汇编指令

比较麻烦

static DWORD g_eax; // 存储返回的eax
static DWORD g_ebx; // 存储返回的ebx
static DWORD g_ecx; // 存储返回的ecx
static DWORD g_edx; // 存储返回的edx

void Executecpuid(DWORD veax)
{
asm("cpuid"
:"=a"(g_eax),
"=b"(g_ebx),
"=c"(g_ecx),
"=d"(g_edx)
:"a"(g_eax));
}
int isSupport;
void GetSerialNumber(WORD nibble[6])
{
Executecpuid(1); // 执行cpuid,参数为 eax = 1
isSupport = g_edx & (1<<18); // edx是否为1代表CPU是否存在序列号
if (FALSE == isSupport) // 不支持,返回false
{
return ;
}
Executecpuid(3); // 执行cpuid,参数为 eax = 3
memcpy(&nibble[4], &g_eax, 4); // eax为最高位的两个WORD
memcpy(&nibble[0], &g_ecx, 8); // ecx 和 edx为低位的4个WORD

}
goodluckyxl 2006-11-10
  • 打赏
  • 举报
回复
在上半年阅读linux内核的时候
我看到获取序列号,硬盘信息是通过中断的函数来读的
int多少我忘记了,你查询一下linux的中断处理函数的内容应该可以找到
richard_ma 2006-11-10
  • 打赏
  • 举报
回复
to yingyi8989(even)

WIN平台是商业的,LINUX是FREE的,而且是开源的
API从来没有公开过它的实现,那样的东西是方便了程序员,但是牺牲了执行效率
INT从某种角度来说也是一种API,想早期的DOS,也是用INT的,只不过是用汇编实现的
huoyingrenzhe 2006-11-10
  • 打赏
  • 举报
回复
路过....

飘过....
yingyi8989 2006-11-10
  • 打赏
  • 举报
回复
to goodluckyxl(被人遗忘的狗):
Linux下面不没有像WIN32平台一样,可以直接调用API来实现呢?

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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