当前位置:首页 » 编程语言 » c语言如何读取bios信息
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

c语言如何读取bios信息

发布时间: 2022-12-14 14:03:19

⑴ 如何通过使用c/c++读取内存中的BIOS信息并得到CPU的温度

using namespace System;

int main(array<System::String ^> ^args)
{
array<System::String^> ^strings = ;
for (int i = 0; i < strings->Length; i++)
{
Console::Write(strings[i]);
}
Console::ReadKey();
return 0;
}

VS自动生成的main函数不是已经给出String数组的声明方式了吗?

---------------------------------------------
很奇怪的补充问题!
为什么不用这种方式,而要去另外探究其他方式?

就像问--<“^”符号来表示指针外,就不能用其他方式来表示了吗?>
这样的问法,怎么回答呢?目的何在?

c语言编程怎样从SMBIOS读取BIOS版本

bios是电脑的重要程序之一,也是主板的必备程序,下面我们来说说如何查看bios版本以及发布日期。 首先,鼠标单击“开始”菜单,选择“附件” 2 在“附件”目录下,选择“系统工具”- “系统信息” 3 在“系统信息”窗口加载完毕后

⑶ c语言中的bioskey()

bioskey()接收的是扫描码。
函 数 名: bioskey 头文件:bios.h
功 能: 直接使用BIOS服务的键盘接口(也可以理解为:读取键盘值)
用 法: int bioskey(int cmd);
输入参数:cmd=0 返回一个键盘值,如无键盘按下,一直等待。

cmd=1 查询键盘是否按下 0-无键按下,非0-有键按下。

cmd=2 返回控制键状态,返回值保存在低8位中。

#define NUM1 0x4f31 /* 小键盘区上数字键1 */
#define NUM2 0x5032 /* 小键盘区上数字键2 */
#define NUM3 0x5133 /* 小键盘区上数字键3 */
#define NUM4 0x4b34 /* 小键盘区上数字键4 */
#define NUM5 0x4c35 /* 小键盘区上数字键5 */
#define NUM6 0x4d36 /* 小键盘区上数字键6 */
#define NUM7 0x4737 /* 小键盘区上数字键7 */
#define NUM8 0x4838 /* 小键盘区上数字键8 */
#define NUM9 0x4939 /* 小键盘区上数字键9 */
#define NUMPNT 0x532e /* 小键盘区上 . 键 */
#define NUMADD 0x4e2b /* 小键盘区上 + 键 */
#define NUMSUB 0x4a2d /* 小键盘区上 - 键 */
#define NUMMUL 0x372a /* 小键盘区上 * 键 */
#define NUMDIV 0x352f /* 小键盘区上 / 键 */
#define NUMEQU 0x1c0d /* 小键盘区上 = 键 */#define KEY0 0xb30 /* 主键盘区上数字键0 */
#define KEY1 0x231 /* 主键盘区上数字键1 */
#define KEY2 0x332 /* 主键盘区上数字键2 */
#define KEY3 0x433 /* 主键盘区上数字键3 */
#define KEY4 0x534 /* 主键盘区上数字键4 */
#define KEY5 0x635 /* 主键盘区上数字键5 */
#define KEY6 0x736 /* 主键盘区上数字键6 */
#define KEY7 0x837 /* 主键盘区上数字键7 */
#define KEY8 0x938 /* 主键盘区上数字键8 */
#define KEY9 0xa39 /* 主键盘区上数字键9 */
#define KEYPNT 0x342e /* 主键盘区上 . 键 */
#define KEYSUB 0xc2d /* 主键盘区上 - 键 */
#define KEYMUL 0x92a /* 主键盘区上 * 键 */
#define KEYEQU 0xd3d /* 主键盘区上 = 键

⑷ 求c语言中的bioskey的用法呀

bioskey(1)检测是否有键按下,没有键按下时返回0,有键按下时返回按键码(任何按键码都不为0),但此时并不将检测到的按键码从键盘缓冲队列中清除.
bioskey(0)返回键盘缓冲队列中的按键码,并将此按键码从键盘缓冲队列中清除.
bioskey(2)返回按键的状态(如组合键等),返回的整数中的每一个位含义如下:

┌——┬———————————┬———————————┐
│ 位 |为0时意义 │为1时意义 │
├——┼———————————┼———————————┤
│ 7 │插入状态 │改写状态 │
│ 6 │大写状态 │小写状态 │
│ 5 │数字状态,NumLock灯亮│光标状态,NumLock灯熄 │
│ 4 │ScrollLock灯亮 │ScrollLock灯熄 │
│ 3 │Alt按下 │Alt未按下 │
│ 2 │Ctrl按下 │Ctrl未按下 │
│ 1 │左Shift按下 │左Shift未按下 │
│ 0 │右Shift按下 │右Shift未按下 │
└——┴———————————┴———————————┘

这些都是从 C函数速查 中找的,大家可以从网上搜一下.bioskey()是返回键盘状态的基本函数,它拥有3个参数
函数原型为:

int bioskey(int cmd)

其中cmd有3个参数:0,1,2

各参数的用法为:

当cmd是0,bioskey()返回下一个在键盘键入的值(它将等待到按下一个键)。它返回一个16位的二进制数,包括两个不同的值。当按下一个普通键时,它的低8位数存放该字符的ASCII码;对于特殊键(如方向键、F1~F12等等),低8位为0,高8位字节存放该键的扫描码。
cmd = 1:
当cmd是1,bioskey()查询是否按下一个键,若按下一个键则返回非零值,否则返回0。
cmd = 2:
当cmd是2,bioskey()返回Shift、Ctrl、Alt、ScrollLock、NumLock、CapsLock、Insert键的状态。各键状态存放在返回值的低8位字节中。
字节位 含义
0 右边Shift键状态
1 左边Shift键状态
3 Ctrl键状态
4 Alt键状态
5 ScrollLock键状态
6 NumLock键状态
7 CapsLock键状态
8 Insert键状态bioskey函数
函数原型: int bioskey(int cmd);
函数功能:
利用函数bioskey可以实现三种功能,参数cmd为要实现的功能号,值只能为0、1、2,具
体含义如下:
0:在系统中有一个按键队列,所有的键盘按键都在这里排成队。该功能就是如果按键队
列中有按键,那么读取队列首位的按键,并返回按键值;否则等待键盘按键出现。(其
中按键值的高字节为扫描码,低字节为ASCII码)
1:如果按键队列中没有按键,那么返回零,否则返回非零。
2:返回特殊按键Shift、Ctrl、Alt等键的按键状态
bioskey函数用于从内存中读取一个按键的scancode值.
格式是: int bioskey(int cmd)
参数cmd取值:
0: 读取scancode,并从内存中删除,如果没有按键则等待.
1: 读取scancode,但不从内存中删除(其它函数可以继续使用),如果无按键则返回0
2: 返加shift alt ctrl键的状态
按下shift返回1,按下ctrl返回4,按下alt返回8,
如果是 shift+ctrl 则返回5(相加),依此类推....下面是一个例子:
#include <bios.h>
main()
{
while(!kbhit())
{
printf("\n%d,%d",bioskey(0),bioskey(2));
}
}
注意:这是一个死循环,因为参数0表示接收按键码,但将其清除,所以kbhit()函数就接收不到按键了.
可按ctrl+break组合键来终止这个程序.然后将 bioskey(0)改为 bioskey(1),
如果不按键将显示0,若按键则立即结束

函数名: bioskey
功 能: 直接使用BIOS服务的键盘接口
函数原型:int bioskey (int cmd)
说明:bioskey()的函数原型在bios.h中
bioskey()完成直接键盘操作,cmd的值决定执行什么操作。
cmd = 0:
当cmd是0,bioskey()返回下一个在键盘键入的值(它将等待到按下一个键)。它返回一个16位的二进制数,包括两个不同的值。当按下一个普通键时,它的低8位数存放该字符的ASCII码;对于特殊键(如方向键、F1~F12等等),低8位为0,高8位字节存放该键的扫描码。
cmd = 1:
当cmd是1,bioskey()查询是否按下一个键,若按下一个键则返回非零值,否则返回0。
cmd = 2:
当cmd是2,bioskey()返回Shift、Ctrl、Alt、ScrollLock、NumLock、CapsLock、Insert键的状态。各键状态存放在返回值的低8位字节中。

字节位 含义
0 右边Shift键状态
1 左边Shift键状态
3 Ctrl键状态
4 Alt键状态
5 ScrollLock键状态
6 NumLock键状态
7 CapsLock键状态
8 Insert键状态

字节位为1表示该键被按下,为0表示松开。
程序例:

#include <stdio.h>
#include <bios.h>
#include <ctype.h>

#define RIGHT 0x01
#define LEFT 0x02
#define CTRL 0x04
#define ALT 0x08

int main(void)
{
int key, modifiers;

/* function 1 returns 0 until a key is pressed */
while (bioskey(1) == 0);

/* function 0 returns the key that is waiting */
key = bioskey(0);

/* use function 2 to determine if shift keys were used */
modifiers = bioskey(2);
if (modifiers)
{
printf("[");
if (modifiers & RIGHT) printf("RIGHT");
if (modifiers & LEFT) printf("LEFT");
if (modifiers & CTRL) printf("CTRL");
if (modifiers & ALT) printf("ALT");
printf("]");
}
/* print out the character read */
if (isalnum(key & 0xFF))
printf("'%c'\n", key);
else
printf("%#02x\n", key);
return 0;
}

bioskey 返回的值有两种情况。
就 ASCII 而言:按一个按键会有两种情况发生。
1.按一个按键,产生一个ASCII,这样 bioskey 返回的值就是:hi:扫描码,lo:ASCII
2.按一个按键,产生两个ASCII,一个是0,另一个是每个键不同的ASCII, bioskey 的返回值就是:hi:ASCII, lo:0
有很多键没有ASCII,例如Shift, Ctrl, CapsLock 等,但是他们有扫描码,只要是按键就有扫描码。

扫描码和ASCII是完全不同的两个概念,是硬件识别键盘的编码,每个按键都有固定的扫描码,用来区别每个按键,不同的按键的扫描码都不同。
两个按键的ASCII有可能相同,但是扫描码一定不同,只要是两个键,扫描码就不同,例如两个回车,ASCII相同,但是扫描码不同。

我以前的程序编过一段扫描码,贴出来给你看看:(7年前编的,本来是我当时想做的一个游戏引擎的一段程序,可以判断和处理键盘上任意多个键同时按下/抬起的情况,可惜因种种原因中断了,因DOS程序,现在也没什么意义了)
扫描码的D7位为0,表示这个按键被按下产生的中断,D7为1表示这个按键被抬起产生的中断。

//特殊按键
//Pause = 0xe145 / 0xe1c5 (0xe1,0x1d(Ctrl),0x45(NumLock) - 0xe1,0x9d,0xc5)
//Break = 0xe046 / 0xe0c6 (0xe0, ScrollLock)
//PrtSc = 0xe037 / 0xe0b7 (0xe0, KeyPad - *)
//SysRq = Ctrl - PrtSc

char PauseKeyName=
{
"NULL", //00
"Esc", //01
"1 !", //02
"2 @", //03
"3 #", //04
"4 $", //05
"5 %", //06
"6 ^", //07
"7 &", //08
"8 *", //09
"9 (", //0A
"0 )", //0B
"- _", //0C
"+ =", //0D
"BackSpace", //0E
"Tab", //0F
"Q", //10
"W", //11
"E", //12
"R", //13
"T", //14
"Y", //15
"U", //16
"I", //17
"O", //18
"P", //19
" }", //1B
"Enter", //1C
"L-Ctrl", //1D
"A", //1E
"S", //1F
"D", //20
"F", //21
"G", //22
"H", //23
"J", //24
"K", //25
"L", //26
"; :", //27
"" \"", //28
"` ~", //29
"L-Shift", //2A
"\\ |", //2B
"Z", //2C
"X", //2D
"C", //2E
"V", //2F
"B", //30
"N", //31
"M", //32
", <", //33
". >", //34
"/ ?", //35
"R-Shift", //36
" *", //37
"L-Alt", //38
"Space", //39
"CapsLock", //3A
"F1", //3B
"F2", //3C
"F3", //3D
"F4", //3E
"F5", //3F
"F6", //40
"F7", //41
"F8", //42
"F9", //43
"F10", //44
"NumLock", //45
"ScrollLock",//46
" 7 Home", //47
" 8 Up", //48
" 9 PgUp", //49
" -", //4A
" 4 Left", //4B
" 5", //4C
" 6 Right", //4D
" +", //4E
" 1 End", //4F
" 2 Down", //50
" 3 PgDn", //51
" 0 Ins", //52
" . Del", //53
"PrtSc(Alt)",//54
"??? 55H", //55
"Added \\ |",//56
"F11", //57
"F12", //58
"??? 59H", //59
"??? 5AH", //5A
"??? 5BH", //5B
"??? 5CH", //5C
"??? 5DH", //5D
"??? 5EH", //5E
"??? 5FH", //5F
"??? 60H", //60
"??? 61H", //61
"??? 62H", //62
"??? 63H", //63
};

char KeyNamesE0=
{
"NULL", //E000
"??? E001H", //E001
"??? E002H", //E002
"??? E003H", //E003
"??? E004H", //E004
"??? E005H", //E005
"??? E006H", //E006
"??? E007H", //E007
"??? E008H", //E008
"??? E009H", //E009
"??? E00AH", //E00A
"??? E00BH", //E00B
"??? E00CH", //E00C
"??? E00DH", //E00D
"??? E00EH", //E00E
"??? E00FH", //E00F
"??? E010H", //E010
"??? E011H", //E011
"??? E012H", //E012
"??? E013H", //E013
"??? E014H", //E014
"??? E015H", //E015
"??? E016H", //E016
"??? E017H", //E017
"??? E018H", //E018
"??? E019H", //E019
"??? E01AH", //E01A
"??? E01BH", //E01B
" Enter", //E01C
"R-Ctrl", //E01D
"??? E01EH", //E01E
"??? E01FH", //E01F
"??? E020H", //E020
"??? E021H", //E021
"??? E022H", //E022
"??? E023H", //E023
"??? E024H", //E024
"??? E025H", //E025
"??? E026H", //E026
"??? E027H", //E027
"??? E028H", //E028
"??? E029H", //E029
"??? E02AH", //E02A
"??? E02BH", //E02B
"??? E02CH", //E02C
"??? E02DH", //E02D
"??? E02EH", //E02E
"??? E02FH", //E02F
"??? E030H", //E030
"??? E031H", //E031
"??? E032H", //E032
"??? E033H", //E033
"??? E034H", //E034
" /", //E035
"??? E036H", //E036
"PrtSc", //E037
"R-Alt", //E038
"??? E039H", //E039
"??? E03AH", //E03A
"??? E03BH", //E03B
"??? E03CH", //E03C
"??? E03DH", //E03D
"??? E03EH", //E03E
"??? E03FH", //E03F
"??? E040H", //E040
"??? E041H", //E041
"??? E042H", //E042
"??? E043H", //E043
"??? E044H", //E044
"??? E045H", //E045
"Break", //E046
"Home", //E047
"Up", //E048
"PageUp", //E049
"??? E04AH", //E04A
"Left", //E04B
"??? E04CH", //E04C
"Right", //E04D
"??? E04EH", //E04E
"End", //E04F
"Down", //E050
"PageDown", //E051
"Insert", //E052
"Delete", //E053
"??? E054H", //E054
"??? E055H", //E055
"??? E056H", //E056
"??? E057H", //E057
"??? E058H", //E058
"??? E059H", //E059
"??? E05AH", //E05A
"L-Start95", //E05B
"R-Start95", //E05C
"Menu95", //E05D
"Power", //E05E
"Sleep", //E05F
"??? E060", //E060
"??? E061", //E061
"??? E062", //E062
"Wake Up", //E063
};

得到扫描码的方法:拦截键盘硬体中断,计算的结果保存在 KeyScanCode 里,KeyboardProc();就是处理这个值的函数。

unsigned far *_Key_Flags = (unsigned far *)0x00000417L;
unsigned far *_Key_Flags1= (unsigned far *)0x00000496L;
unsigned int far KeyScanCode = 0;
unsigned char far KeyScBuffer={0,0,0,0};
unsigned char far KeyTempChar = 0;

void interrupt NewKb09(...)
{
asm cli
KeyTempChar=inportb(0x60);

KeyScBuffer=KeyScBuffer;
KeyScBuffer=KeyScBuffer;
KeyScBuffer=KeyScBuffer;
KeyScBuffer=KeyTempChar;

KeyTempChar=inportb(0x61);
outportb(0x61,KeyTempChar|0x80);
outportb(0x61,KeyTempChar&0x7f);

if((KeyScBuffer!=0xe0) && (KeyScBuffer!=0xe1))
{
KeyScanCode=KeyScBuffer;
if(KeyScBuffer==0xe0)
KeyScanCode|=0xe000;

if((KeyScBuffer==0xe1) &&
((KeyScBuffer==0x1d) || (KeyScBuffer==0x9d)))
KeyScanCode|=0xe100;

if((KeyScanCode!=0xe02a) &&
(KeyScanCode!=0xe0aa) &&
(KeyScanCode!=0xe036) &&
(KeyScanCode!=0xe0b6) &&
(KeyScBuffer!=0xe1))
KeyboardProc();
}

asm sti
outportb(0x20,0x20);
}

//这是一段测试程序,可以显示出当前按下或者抬起那个按键:

char FmtKscCode="%-10s\r\n";
char FmtUnkName="\rScanCode: ";
char StrKeyName="Press any key or Esc to quit ...";
char ByeStr);
}
else
{
cprintf(FmtKeyName, KeyNames00);
}
}
else
{
cprintf(FmtUnkName, ksCode&0xff7f);
}

textcolor(LIGHTBLUE);
cprintf(StrWait);

ksCode=0;
}
}

textcolor(LIGHTGRAY);
cprintf(ByeStr);

ResOldKb();
return 0;
}
Top

⑸ 如何用c语言读取bios信息

如果在c中要用到biosdisk这个函数,就必须有这个文件,这个函数的功能是可以直接访问硬盘扇区

⑹ 请问在C语言中,头文件bios.h中的biosdisk这个函数怎么用有什么用途编一个给我

函数名: biosdisk
功 能: 软硬盘I/O
用 法: int biosdisk(int cmd, int drive, int head, int track, int sector
int nsects, void *buffer); 本函数用来对驱动器作一定的操作,cmd为功能号,
drive为驱动器号(0=A,1=B,0x80=C,0x81=D,0x82=E等)。

cmd可为以下值:
0 重置软磁盘系统.这强迫驱动器控制器来执行硬复位.忽略所有其它参数.
1 返回最后的硬盘操作状态.忽略所有其它参数
2 读一个或多个磁盘扇区到内存.读开始的扇区由head、track、sector给出。
扇区号由nsects给出。把每个扇区512个字节的数据读入buffer
3 从内存读数据写到一个或多个扇区。写开始的扇区由head、track、sector
给出。扇区号由nsects给出。所写数据在buffer中,每扇区512个字节。
4 检验一个或多个扇区。开始扇区由head、track、sector给出。扇区号由
nsects给出。
5 格式化一个磁道,该磁道由head和track给出。buffer指向写在指定track上
的扇区磁头器的一个表。
以下cmd值只允许用于XT或AT微机:
6 格式化一个磁道,并置坏扇区标志。
7 格式化指定磁道上的驱动器开头。
8 返回当前驱动器参数,驱动器信息返回写在buffer中(以四个字节表示)。
9 初始化一对驱动器特性。
10 执行一个长的读,每个扇区读512加4个额外字节
11 执行一个长的写,每个扇区写512加4个额外字节
12 执行一个磁盘查找
13 交替磁盘复位
14 读扇区缓冲区
15 写扇区缓冲区
16 检查指定的驱动器是否就绪
17 复核驱动器
18 控制器RAM诊断
19 驱动器诊断
20 控制器内部诊 函数返回由下列位组合成的状态字节:
0x00 操作成功
0x01 坏的命令
0x02 地址标记找不到
0x04 记录找不到
0x05 重置失败
0x07 驱动参数活动失败
0x09 企图DMA经过64K界限
0x0B 检查坏的磁盘标记
0x10 坏的ECC在磁盘上读
0x11 ECC校正的数据错误(注意它不是错误)
0x20 控制器失效
0x40 查找失败
0x80 响应的连接失败
0xBB 出现无定义错误
0xFF 读出操作失败程序例:
// main.c
#include <stdio.h>
#include <bios.h>
#include "floppyio.h"
int main(void)
{
char buf[512] = "Hello, world!"; int r; FILE *fp = fopen("booter.exe", "rb");
fread(buf, 1, 512, fp);
fclose(fp); printf("floppy ready : %d\n", IsFloppyReady());
buf[510] = 0x55;
buf[511] = 0xaa; printf("write: %d,%d\n", buf[510], buf[511]);
r = WriteFloppyBootSection(buf);
printf("r=%d\n", r);
return 0;
}
// FloppyIO.h
/* defines */
#define FLOPPY_READ 2
#define FLOPPY_WRITE 3
#define FLOPPY_READY 4/* test if floppy is ready now, if so return 1, else 0 */
int IsFloppyReady(void); /* write first head 0 /track 0 /sector 1 of floppy disk (boot section, 512 bytes) */
int WriteFloppyBootSection(char* buffer);/* read first head 0 /track 0 /sector 1 of floppy disk (boot section, 512 bytes) */
int ReadFloppyBootSection(char* buffer);
// FloppyIO.c
#include "FloppyIO.h"
int IsFloppyReady(void)
{
int result;
char buffer[512]; result = biosdisk(FLOPPY_READY, 0, 0, 0, 1, 1, buffer);

return ( result == 0 ? 1 : 0 );
}int WriteFloppyBootSection(char* buffer)
{
int result; result = biosdisk(FLOPPY_WRITE, 0, 0, 0, 1, 1, buffer);

return ( result == 0 ? 1 : 0 );
}int ReadFloppyBootSection(char* buffer)
{
int result;

result = biosdisk(FLOPPY_READ, 0, 0, 0, 1, 1, buffer);

return ( result == 0 ? 1 : 0 );
}

⑺ 如何读取bios信息

电脑打开BIOS系统界面需要重启电脑后立即按住del键,就可以 进入BIOS界面,读取BIOS节目的信息一般都是选择启动设备的,比如安装系统前需要设置USB,或者光驱第一个启动。

⑻ 怎么读取BIOS的设置信息,比如密码!

这个不在行,不好意思哦!

⑼ 如何用VC++读取BIOS的版本号等信息。奖励100分

可能需要ddk,否则有些结构可能没有,可以回帖我补上

#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <RegStr.h>
#include <winioctl.h>
#include <ntddndis.h>

//结构定义
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING,*PUNICODE_STRING;

typedef struct _OBJECT_ATTRIBUTES
{
ULONG Length; // 长度 18h
HANDLE RootDirectory; // 00000000
PUNICODE_STRING ObjectName; // 指向对象名的指针
ULONG Attributes; // 对象属性00000040h
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);

/*====================================================================
函数 : FindAwardBios
功能 : 获取Award 系列的Bios序列号
输入 : TSystemInfo& tSystemInfo [OUT]
输出 : TSystemInfo
返回 : FALSE 表示获取失败
======================================================================*/
UINT FindAwardBios( BYTE** ppBiosAddr )
{
BYTE* pBiosAddr = * ppBiosAddr + 0xEC71;
BYTE szBiosData[128];

::CopyMemory( szBiosData, pBiosAddr, 127 );
szBiosData[127] = 0;

int iLen = lstrlen( ( char* )szBiosData );
if( iLen > 0 && iLen < 128 )
{
//AWard: 07/08/2002-i845G-ITE8712-JF69VD0CC-00
//Phoenix-Award: 03/12/2002-sis645-p4s333

if( szBiosData[2] == '/' && szBiosData[5] == '/' )
{
BYTE* p = szBiosData;
while( * p )
{
if( * p < ' ' || * p >= 127 )
{
break;
}
++ p;
}

if( * p == 0 )
{
* ppBiosAddr = pBiosAddr;
return ( UINT )iLen;
}
}
}
return 0;
}

/*====================================================================
函数 : FindAmiBios
功能 : 获取Ami 系列的Bios序列号
输入 : TSystemInfo& tSystemInfo [OUT]
输出 : TSystemInfo
返回 : FALSE 表示获取失败
======================================================================*/
UINT FindAmiBios( BYTE** ppBiosAddr )
{
BYTE* pBiosAddr = * ppBiosAddr + 0xF478;

BYTE szBiosData[128];
::CopyMemory( szBiosData, pBiosAddr, 127 );
szBiosData[127] = 0;

int iLen = lstrlen( ( char* )szBiosData );
if( iLen > 0 && iLen < 128 )
{
// Example: "AMI: 51-2300-000000-00101111-030199-"
if( szBiosData[2] == '-' && szBiosData[7] == '-' )
{
BYTE* p = szBiosData;
while( * p )
{
if( * p < ' ' || * p >= 127 )
{
break;
}
++ p;
}
if( * p == 0 )
{
* ppBiosAddr = pBiosAddr;
return ( UINT )iLen;
}
}
}

return 0;
}

/*====================================================================
函数 : FindPhoenixBios
功能 : 获取Phoenix 系列的Bios序列号
输入 : TSystemInfo& tSystemInfo [OUT]
输出 : TSystemInfo
返回 : FALSE 表示获取失败
======================================================================*/
UINT FindPhoenixBios( BYTE** ppBiosAddr )
{
UINT uOffset[3] = { 0x6577, 0x7196, 0x7550 };
for( UINT i = 0; i < 3; ++ i )
{
BYTE* pBiosAddr = * ppBiosAddr + uOffset[i];
BYTE szBiosData[128];
::CopyMemory( szBiosData, pBiosAddr, 127 );
szBiosData[127] = 0;

int iLen = lstrlen( ( char* )szBiosData );
if( iLen > 0 && iLen < 128 )
{
// Example: Phoenix "NITELT0.86B.0044.P11.9910111055"
if ( szBiosData[7] == '.' && szBiosData[11] == '.' )
{
BYTE* p = szBiosData;
while( * p )
{
if( * p < ' ' || * p >= 127 )
{
break;
}
++ p;
}
if( * p == 0 )
{
* ppBiosAddr = pBiosAddr;
return ( UINT )iLen;
}
}
}
}

return 0;
}

/*====================================================================
函数 : GetBiosSerialNum
功能 : 获取Bios序列号
输入 : TSystemInfo& tSystemInfo [OUT]
输出 : TSystemInfo
返回 : FALSE 表示获取失败
======================================================================*/
BOOL GetBiosSerialNum(TSystemInfo& tSystemInfo)
{
SIZE_T ssize;
LARGE_INTEGER so;
so.LowPart=0x000f0000;
so.HighPart=0x00000000;
ssize=0xffff;

wchar_t strPH[30]= L"\\device\\physicalmemory";

DWORD ba=0;
UNICODE_STRING struniph;
struniph.Buffer=strPH;
struniph.Length=0x2c;
struniph.MaximumLength =0x2e;
OBJECT_ATTRIBUTES obj_ar;
obj_ar.Attributes =64;
obj_ar.Length =24;
obj_ar.ObjectName=&struniph;
obj_ar.RootDirectory=0;
obj_ar.SecurityDescriptor=0;
obj_ar.SecurityQualityOfService =0;

HMODULE hinstLib = LoadLibrary("ntdll.dll");
ZWOS ZWopenS=(ZWOS)GetProcAddress(hinstLib,"ZwOpenSection");
ZWMV ZWmapV=(ZWMV)GetProcAddress(hinstLib,"ZwMapViewOfSection");
ZWUMV ZWunmapV=(ZWUMV)GetProcAddress(hinstLib,"ZwUnmapViewOfSection");

//调用函数,对物理内存进行映射
HANDLE hSection;
if( 0 == ZWopenS(&hSection,4,&obj_ar) &&
0 == ZWmapV(
( HANDLE )hSection, //打开Section时得到的句柄
( HANDLE )0xFFFFFFFF, //将要映射进程的句柄,
&ba, //映射的基址
0,
0xFFFF, //分配的大小
&so, //物理内存的地址
&ssize, //指向读取内存块大小的指针
1, //子进程的可继承性设定
0, //分配类型
2 //保护类型
)
)
//执行后会在当前进程的空间开辟一段64k的空间,并把f000:0000到f000:ffff处的内容映射到这里
//映射的基址由ba返回,如果映射不再有用,应该用ZwUnmapViewOfSection断开映射
{
BYTE* pBiosSerial = ( BYTE* )ba;
UINT uBiosSerialLen = FindAwardBios( &pBiosSerial );
if( uBiosSerialLen == 0U )
{
uBiosSerialLen = FindAmiBios( &pBiosSerial );
if( uBiosSerialLen == 0U )
{
uBiosSerialLen = FindPhoenixBios( &pBiosSerial );
}
}

if( uBiosSerialLen != 0U )
{
tSystemInfo.Append((u8*)"BIOS=", 5);
::CopyMemory( tSystemInfo.szInfo+5, pBiosSerial, uBiosSerialLen );
tSystemInfo.dwRealSize = uBiosSerialLen+5;
}
else
{
printf("BIOS: not support!\n");
return FALSE;
}

ZWunmapV( ( HANDLE )0xFFFFFFFF, ( void* )ba );

printf("BIOS: %s\n", (s8*)tSystemInfo.szInfo);

return TRUE;
}

printf("BIOS: not supported!\n");
return FALSE;
}