BCB直接訪問硬體埠和實體記憶體 - WinIO的應用 |
|
conundrum
尊榮會員 發表:893 回覆:1272 積分:643 註冊:2004-01-06 發送簡訊給我 |
BCB直接訪問硬體埠和實體記憶體 - WinIO的應用 http://www.cppfans.com/articles/system/portrw_winio.asp (讀硬碟參數和主板BIOS資訊, 支援 Win9x/NT/2k/XP/2003) Victor Chen, (C++ 愛好者) 附完整的根源程式(本頁最下面的鏈結) 關於直接訪問埠, 有很多網站很多文章都討論過, 但總找不到非常理想的辦法。
我這裏用的是 Yariv Kaplan 的 WinIo 2.0。雖然 WinIO 也有缺陷, 但是是我用過的當中最好的了。
WinIO 是免費的, 並且是開放源代碼的, 可以直接到他的主頁下載, 也可以在這裏下載。
Yariv Kaplan 的主頁: http://www.internals.com/ WinIO 的使用非常簡單, 在程式的開始調用 InitializeWinIo(); 初始化 WinIO, 在程式的結束使用 ShutdownWinIo();
這樣就可以在程式裏直接訪問埠和實體記憶體了。 在這裏仍然用的是讀硬碟參數和主板BIOS資訊。
本站在《硬碟參數讀取程式》這篇文章裏曾經介紹過利用 WinIO 讀取硬碟參數, 很多人提出程式太複雜, 並且在程式妍坋刓掍庛g常無效,
在這裏簡化了程式, 並且改善了性能, 在程式妍坋刓掍峇]可讀出參數了。 按鈕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
有關讀寫埠函數 inportb 和 outportb 等函數: 在 Win2000 等 NT 內核的 OS 可直接用彙編訪問埠, 但 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; } } 上面的程式 InitPortFuncs 就是判斷作業系統是否d NT 內核, 並且選擇合適的函數來訪問埠。 經過這樣處理, 在 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發表人 - conundrum 於 2004/02/14 11:11:33
附加檔案:44873_BCB_IO.rar
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |