Windows 内核 I/O 端口操作
这只是一篇读书笔记。
1. C语言提供的端口函数
C语言提供了操作I/O端口的函数。这些函数会电泳IN 和OUT 汇编指令。 当然这些函数只能在内核模式下执行。
我们可以自定了如下的函数:
1 #pragma INITCODE
2 ULONG In_32(PULONG port)
3 {
4 ULONG value;
5 _asm
6 {
7 mov edx, port //将端口号传入EDX中
8 in eax, dx //执行32位IO输入
9 mov value,eax
10 //插入几个空指令
11 nop
12 nop
13 }
14 return(value);
15 }
16 #pragma INITCODE
17 void Out_32(PULONG port, ULONG value)
18 {
19 _asm
20 {
21 mov edx, port
22 mov eax, value
23 out dx, eax
24 nop
25 nop
26 }
27 }
2. DDK 的端口操作函数
DDK 同样提供了类似的端口操作函数。
函数名 | 描述 |
READ_PORT_UCHAR | 8位输入 |
READ_PORT_USHORT | 16位输入 |
READ_PORT_ULONG | 32位输入 |
READ_PORT_BUFFER_UCHAR | 8位连续输入 |
READ_PORT_BUFFER_USHORT | 16位连续输入 |
READ_PORT_BUFFER_ULONG | 32位连续输入 |
WRITE_PORT_UCHAR | 8位输出 |
WRITE_PORT_USHORT | 16位输出 |
WRITE_PORT_ULONG | 32位输出 |
WRITE_PORT_BUFFER_UCHAR | 8位连续输出 |
WRITE_PORT_BUFFER_USHORT | 16位连续输出 |
WRITE_PORT_BUFFER_ULONG | 32位连续输出 |
需要注意的是编译的时候需要加入HAL.lib库。
3. WinIo
WinIo 通过内核模式下设备驱动和其他一些底层的编程技巧绕过了windows安全保护机制,允许32位windows程序直接对I/O端口进行操作。在windows NT/2000/XP下,WinIo库只允许具有管理员权限的应用程序调用。
winIo的使用就非常简单了,如:
1 int main()
2 {
3 //打开WinIO驱动
4 bool bRet = InitializeWinIo();
5 if (bRet)
6 {
7 printf("Load Dirver successfully!\n");
8 //对0x378端口进行输出操作,8位操作
9 SetPortVal(0x378,0,1);
10 //关闭WinIO驱动
11 ShutdownWinIo();
12 }
13 return 0;
14 }