Windows下設置端口權限的系統調用有兩個:ioperm和iopl函數
1.ioperm函數
功能描述:
為調用進程設置I/O端口訪問權能。ioperm的使用需要具有超級用戶的權限,只有低端的[0-0x3ff] I/O端口可被設置,要想指定更多端口的權能,可使用iopl函數。這一調用只可用於i386平台。
用法:
[cpp]
#include <ioperm.h>/* for libc5 */
#include <sys/io.h>/* for glibc */
int ioperm(unsigned long from, unsigned long num, int turn_on);
#include <ioperm.h>/* for libc5 */
#include <sys/io.h>/* for glibc */
int ioperm(unsigned long from, unsigned long num, int turn_on);參數:
from:起始端口地址。
num:需要修改權能的端口數。
turn_on:端口的新權能位。1為開啟,0為關閉。
返回說明:
成功執行時,返回0。失敗返回-1,errno被設為以下的某個值
EINVAL:參數無效
EIO:這一調用不被支持
EPERM:調用進程權能不足。
2.iopl函數
功能描述:該調用用於修改當前進程的操作端口的權限。可以用於所有65536個端口的權限。因此,ioperm相當於該調用的子集。和ioperm一樣,這一調用僅適用於i386平台。
用法:
[cpp]
#include <ioperm.h>
int iopl(int level);
#include <ioperm.h>
int iopl(int level);參數:
level: 端口的權限級別。為3時可以讀寫端口。默認權能級別為0,用戶空間不可讀寫。
返回說明:成功執行時,返回0。失敗返回-1,errno被設為以下的某個值
EINVAL:level值大於3
ENOSYS:未實現該調用
EPERM:調用進程權能不足。
目前已經將主要的部分更改成支持GCC編譯的內容。支持GCC內聯匯編。
代碼如下(默認用Windows的C編譯器):
[cpp]
/*
* function: read cmos data using rtc port(0x70 -- port, 0x71 -- data)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
extern int install( int );
extern int uninstall(int );
extern ioperm( unsigned long from, unsigned long num, int turn_on );
#ifdef _GCC
void outp(unsigned short addr, unsigned short data){
__asm__ (
"mov %1, %%al;"
"mov %0, %%dx;"
"out %%al, %%dx;"
: /* no output */
:"m" (addr), "m" (data) /* input addr and data */
:"ax", "dx"
);
}
unsigned char inp( unsigned short addr)
{
unsigned char cha;
__asm__ (
"mov %1, %%dx;"
"in %%dx, %%al;"
"mov %%al, %0;"
:"=r" (cha) /* output to var(cha) */
:"m" (addr) /* input addr */
: "ax", "dx"
);
return cha;
}
#else /* using windows asm */
void outp(unsigned short addr , unsigned short data){
asm {
mov al,data
mov dx,addr
out dx,al
}
}
unsigned char inp( unsigned short addr)
{
unsigned char cha;
asm{
mov dx,addr
in al,dx
mov cha ,al
}
return cha;
}
#endif
int main( void )
{
int i;
unsigned char c;
install(0);
Sleep(500);
if (ioperm(0x70, 2, 1 )) {
fprintf( stderr, "Error: ioperm() failed. Please install ioperm.sys driver.\n" );
}else{
for (i=0; i<260; i++)
{
// Sleep(100);
outp(0x70, i);
c = inp(0x71);
printf("%02x ", c);
if ((i+1)%20 == 0)
printf("\n");
}
}
uninstall(0);
return 0;
}
/*
* function: read cmos data using rtc port(0x70 -- port, 0x71 -- data)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
extern int install( int );
extern int uninstall(int );
extern ioperm( unsigned long from, unsigned long num, int turn_on );
#ifdef _GCC
void outp(unsigned short addr, unsigned short data){
__asm__ (
"mov %1, %%al;"
"mov %0, %%dx;"
"out %%al, %%dx;"
: /* no output */
:"m" (addr), "m" (data) /* input addr and data */
:"ax", "dx"
);
}
unsigned char inp( unsigned short addr)
{
unsigned char cha;
__asm__ (
"mov %1, %%dx;"
"in %%dx, %%al;"
"mov %%al, %0;"
:"=r" (cha) /* output to var(cha) */
:"m" (addr) /* input addr */
: "ax", "dx"
);
return cha;
}
#else /* using windows asm */
void outp(unsigned short addr , unsigned short data){
asm {
mov al,data
mov dx,addr
out dx,al
}
}
unsigned char inp( unsigned short addr)
{
unsigned char cha;
asm{
mov dx,addr
in al,dx
mov cha ,al
}
return cha;
}
#endif
int main( void )
{
int i;
unsigned char c;
install(0);
Sleep(500);
if (ioperm(0x70, 2, 1 )) {
fprintf( stderr, "Error: ioperm() failed. Please install ioperm.sys driver.\n" );
}else{
for (i=0; i<260; i++)
{
// Sleep(100);
outp(0x70, i);
c = inp(0x71);
printf("%02x ", c);
if ((i+1)%20 == 0)
printf("\n");
}
}
uninstall(0);
return 0;
}