BCB直接访问硬件端口和物理内存 - WinIO的应用
2011-01-11 11:02
316 查看
http://www.cppfans.com/articles/system/portrw_winio.asp
(读硬盘参数和主板BIOS信息, 支持 Win9x/NT/2k/XP/2003)
(浏览
32444
次)
Victor Chen, (C++
爱好者)
附完整的源程序(本页最下面的链接)
关于直接访问端口, 有很多网站很多文章都讨论过, 但总找不到非常理想的办法。
我这里用的是 Yariv Kaplan 的 WinIo 2.0。虽然 WinIO 也有缺陷, 但是是我用过的当中最好的了。
WinIO 是免费的, 并且是开放源代码的, 可以直接到他的主页下载, 也可以在这里下载。
Yariv Kaplan 的主页: http://www.internals.com/
WinIO 的使用非常简单, 在程序的开始调用 InitializeWinIo(); 初始化 WinIO, 在程序的结束使用 ShutdownWinIo();
这样就可以在程序里直接访问端口和物理内存了。
在这里仍然用的是读硬盘参数和主板BIOS信息。
本站在《硬盘参数读取程序》这篇文章里曾经介绍过利用
WinIO 读取硬盘参数, 很多人提出程序太复杂, 并且在程序启动时调用经常无效,
在这里简化了程序, 并且改善了性能, 在程序启动时调用也可读出参数了。
有关读写端口函数 inportb 和 outportb 等函数: 在 Win2000 等 NT 内核的 OS 可直接用汇编访问端口,
但 Win9x 反而不可以
上面的程序 InitPortFuncs 就是判断操作系统是否为 NT 内核, 并且选择合适的函数来访问端口。
经过这样处理, 在 Win2000 下访问端口的速度就要比 98 的快了, Win2000 的速度比较理想。
具体程序: Button1 是读硬盘参数, Button2 是读主板BIOS信息
最后写一下 WinIO 的缺陷:
会让纯DOS版本的程序无法接受键盘和鼠标事件, 可现在用纯DOS程序很少了, 所以影响不大。
直接访问硬件端口和物理内存-下载完整的程序源代码(BCB5,可以在BCB6下编译通过)
25,438 字节 (下载
7927
次)
源代码本址下载网址:winio_源码.rar
http://files.cnblogs.com/chulia20002001/winio_%e6%ba%90%e7%a0%81.rar
(读硬盘参数和主板BIOS信息, 支持 Win9x/NT/2k/XP/2003)
(浏览
32444
次)
Victor Chen, (C++
爱好者)
附完整的源程序(本页最下面的链接)
关于直接访问端口, 有很多网站很多文章都讨论过, 但总找不到非常理想的办法。
我这里用的是 Yariv Kaplan 的 WinIo 2.0。虽然 WinIO 也有缺陷, 但是是我用过的当中最好的了。
WinIO 是免费的, 并且是开放源代码的, 可以直接到他的主页下载, 也可以在这里下载。
Yariv Kaplan 的主页: http://www.internals.com/
WinIO 的使用非常简单, 在程序的开始调用 InitializeWinIo(); 初始化 WinIO, 在程序的结束使用 ShutdownWinIo();
这样就可以在程序里直接访问端口和物理内存了。
在这里仍然用的是读硬盘参数和主板BIOS信息。
本站在《硬盘参数读取程序》这篇文章里曾经介绍过利用
WinIO 读取硬盘参数, 很多人提出程序太复杂, 并且在程序启动时调用经常无效,
在这里简化了程序, 并且改善了性能, 在程序启动时调用也可读出参数了。
按钮Button1: 硬盘参数: 型 号: MAXTOR 6L040J2 序 列 号: 662202841232 固件版本: AR1.0400 容 量: 38172 Mb 柱 面 数: 16383 磁 头 数: 16 扇 区 数: 63 缓存容量: 1818 kb ECC 字节: 4 bytes LBA 支持: 是 DMA 支持: 是 | 按钮Button2: BIOS信息: Award Modular BIOS v6.00PG Copyright (C) 1984-2001, Award Software, Inc. 05/14/02 05/14/2002-i815-ITE87X2-6A69RPQRS-00 |
但 Win9x 反而不可以
#include "WinIO.h" //--------------------------------------------------------------------------- unsigned char inportbNT(unsigned short p) { asm mov dx, p; asm in al, dx; return _AL; } unsigned short inportwNT(unsigned short p) { asm mov dx, p; asm in ax, dx; return _AX; } unsigned long inportdNT(unsigned short p) { asm mov dx, p; asm in eax,dx; return _EAX;} void outportbNT(unsigned short p, unsigned char v) { asm mov dx, p; asm mov al, v; asm out dx,al; } void outportwNT(unsigned short p, unsigned short v) { asm mov dx, p; asm mov ax, v; asm out dx,ax; } void outportdNT(unsigned short p, unsigned long v) { asm mov dx, p; asm mov eax,v; asm out dx,eax;} //--------------------------------------------------------------------------- unsigned char inportb9x(unsigned short p) { unsigned long v = 0; GetPortVal(p, &v, 1); return v; } unsigned short inportw9x(unsigned short p) { unsigned long v = 0; GetPortVal(p, &v, 2); return v; } unsigned long inportd9x(unsigned short p) { unsigned long v = 0; GetPortVal(p, &v, 4); return v; } void outportb9x(unsigned short p, unsigned char v) { SetPortVal(p,v,1); } void outportw9x(unsigned short p, unsigned short v) { SetPortVal(p,v,2); } void outportd9x(unsigned short p, unsigned long v) { SetPortVal(p,v,4); } //--------------------------------------------------------------------------- unsigned char (*inportb)(unsigned short) = inportbNT; unsigned short (*inportw)(unsigned short) = inportwNT; unsigned long (*inportd)(unsigned short) = inportdNT; void (*outportb)(unsigned short, unsigned char ) = outportbNT; void (*outportw)(unsigned short, unsigned short) = outportwNT; void (*outportd)(unsigned short, unsigned long ) = outportdNT; //--------------------------------------------------------------------------- void InitPortFuncs(void) { OSVERSIONINFO osVer = {sizeof(OSVERSIONINFO)}; GetVersionEx(&osVer); if(osVer.dwPlatformId == VER_PLATFORM_WIN32_NT) { inportb = inportbNT; outportb = outportbNT; inportw = inportwNT; outportw = outportwNT; inportd = inportdNT; outportd = outportdNT; } else { inportb = inportb9x; outportb = outportb9x; inportw = inportw9x; outportw = outportw9x; inportd = inportd9x; outportd = outportd9x; } } |
经过这样处理, 在 Win2000 下访问端口的速度就要比 98 的快了, Win2000 的速度比较理想。
具体程序: Button1 是读硬盘参数, Button2 是读主板BIOS信息
#include "WinIO.h" #pragma link "WinIo_bc.lib" //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { bWinIoInitOK = InitializeWinIo(); if(!bWinIoInitOK) { Application->MessageBox("不能装载 WinIO 程序!","错误信息",MB_OK|MB_ICONSTOP); Application->Terminate(); } InitPortFuncs(); } //--------------------------------------------------------------------------- __fastcall TForm1::~TForm1() { if(bWinIoInitOK) ShutdownWinIo(); } //--------------------------------------------------------------------------- bool ReadHddParams(unsigned short *params, int pn, int dn) { int i,IdePort[2] = {0x1f0, 0x170}; //primary & secondary IDE Controller unsigned char HD_Selection[2]={0xa0,0xb0}; // Master Disk: 1010 0000, Slave Disk: 1011 0000 unsigned short BasePort = IdePort[pn]; for(i=0;i<500;i++) //Get HDC Status, wait until HDC not busy { if((inportb(BasePort+7)&0x80)==0) break; //hdc is ready Sleep(1); } if(i>=300)return false; //HDC no response outportb(BasePort+6, HD_Selection[dn]); //master or slave hard disk outportb(BasePort+7, 0x10); //HDD status for(i=0;i<300;i++) //Get HDD Status, wait until HDD not busy { if((inportb(BasePort+7)&0x80)==0) break; Sleep(1); } if(i>=300)return false; //HDC no response if(inportb(BasePort+7)!=0x50)return false; //HDD ready: 0101 0000 outportb(BasePort+6, HD_Selection[dn]); //master or slave hard disk outportb(BasePort+7, 0xec); //HDD parameters for(i=0;i<300;i++) //wait for parameters retrieved { if(inportb(BasePort+7)==0x58) //retrieved OK break; Sleep(1); } if(i>=300)return false; //parameters retrieved error for(i=0;i<256;i++) params[i]=inportw(BasePort); return true; } //--------------------------------------------------------------------------- void WordToStr(unsigned char *s, unsigned short *w, int n) //硬盘参数转成字符串 { int i; for(i=0; i<n; i++) { s[i*2] = w[i]>>8; s[i*2+1] = w[i]&0x00ff; } s[i*2]=0; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { DWORD dwOldProcessP = GetPriorityClass(GetCurrentProcess()); DWORD dwOldThreadP = GetThreadPriority(GetCurrentThread()); SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); AnsiString idename[2] = {"IDE0","IDE1"}, diskname[2] = {"主盘","从盘"}; unsigned short params[256]; char Str[256]; for(int pn=0; pn<2; pn++) //primary or secondary for(int dn=0; dn<2; dn++) //master or slave { Memo1->Lines->Add(idename[pn]+" "+diskname[dn]+":"); if(ReadHddParams(params,pn,dn)) { WordToStr(Str,params+27,20); Memo1->Lines->Add("型 号: "+AnsiString(Str)); WordToStr(Str,params+10,10); Memo1->Lines->Add("序 列 号: "+AnsiString(Str)); WordToStr(Str,params+23, 4); Memo1->Lines->Add("固件版本: "+AnsiString(Str)); unsigned long LbaCap = *(unsigned long *)(¶ms[60])/2048; unsigned long NomCap = ((unsigned long)(params[1])*(params[3])*(params[6]))/2048; Memo1->Lines->Add("容 量: " + AnsiString().sprintf("%lu Mb",LbaCap>NomCap?LbaCap:NomCap)); Memo1->Lines->Add(AnsiString().sprintf("柱 面 数: %u", params[1])); Memo1->Lines->Add(AnsiString().sprintf("磁 头 数: %u", params[3])); Memo1->Lines->Add(AnsiString().sprintf("扇 区 数: %u", params[6])); bool DMA = params[49]&0x0100; //D8:是否支持DMA bool LBA = params[49]&0x0200; //D9:是否支持LBA Memo1->Lines->Add(AnsiString().sprintf("缓存容量: %u kb", params[21]>>1)); Memo1->Lines->Add(AnsiString().sprintf("ECC 字节: %u bytes", params[22])); Memo1->Lines->Add(AnsiString().sprintf("LBA 支持: %s", LBA?"是":"否")); Memo1->Lines->Add(AnsiString().sprintf("DMA 支持: %s", DMA?"是":"否")); } else { Memo1->Lines->Add("没找到硬盘"); } Memo1->Lines->Add(""); } SetThreadPriority(GetCurrentThread(), dwOldThreadP); SetPriorityClass(GetCurrentProcess(), dwOldProcessP); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { HANDLE hPhyMem; //char *lpInfo = (char far *)0xf0000L; //下面的语句让 0xf0000 地址的 65536 个字节可直接读写 char *lpInfo = MapPhysToLin((char*)0xf0000,65536,&hPhyMem); Memo1->Lines->Add(lpInfo+0xe061); //主板BIOS名称 0xFE061 Memo1->Lines->Add(lpInfo+0xe091); //主板BIOS版权 0xFE091 Memo1->Lines->Add(lpInfo+0xfff5); //主板BIOS日期 0xFFFF5 Memo1->Lines->Add(lpInfo+0xec71); //主板BIOS序列号 0xFEC71 UnmapPhysicalMemory(hPhyMem, lpInfo); } //--------------------------------------------------------------------------- |
会让纯DOS版本的程序无法接受键盘和鼠标事件, 可现在用纯DOS程序很少了, 所以影响不大。
直接访问硬件端口和物理内存-下载完整的程序源代码(BCB5,可以在BCB6下编译通过)
25,438 字节 (下载
7927
次)
源代码本址下载网址:winio_源码.rar
http://files.cnblogs.com/chulia20002001/winio_%e6%ba%90%e7%a0%81.rar
相关文章推荐
- BCB直接访问硬件端口和物理内存 - WinIO的应用
- WinIO--Windows应用程序访问Port端口和物理内存
- tomcat默认访问的项目(域名直接访问项目,不带端口)
- rootkit 直接访问硬件之
- 阿里云ECS Ubuntu 实例开放防火墙端口仍无法访问问题解决(安全组规则应用)
- tomcat中间件访问根域名直接跳转某个应用的首页
- 使用winio对直接访问IO PORT
- Windows防火墙限制端口/IP/应用访问的方法以及例外的配置
- 在NT中直接访问物理内存
- [oralce] 利用CRT的端口转发功能直接用plsql访问数据库
- 同一IP不同端口访问的站点iframe应用session丢失怎么办?
- 解决同一IP不同端口访问的站点iframe应用session丢失的问题
- 动态IP或无公网IP时外网访问内网固定端口管家婆等应用
- 域名解析和端口映射的结合,在任何网络环境发布网站、访问内网,原理分析与实际应用
- 内网服务应用―无需端口映射实现从外网访问控制内网电脑
- 解决同一IP不同端口或跨域访问站点iframe应用session丢失的问与及ASP.NET 开发相关超时设置
- linux下使用apache http server 连接 tomcat 达到使用直接apache一个服务端口就可访问php和jsp
- 用IP加端口直接访问tomcat
- 如何在tomcat里为多个应用配置不同的访问端口
- 使用WinIo直接访问IO