由于Windows的内核保护机制,,我们无法直接对通过内核操作硬件,通过使用WinIo可以绕过这一限制,实现对Windows硬件端口或者地址的直接操作。实际操作中发现WinIo库既可以对普通的I/O端口进行操作,也可以对GPIO进行操作。
关于WinIO的相关内容网络上的参考资料很多,这里只记录我自己遇到的问题(使用中需要注意的点):
1.64位操作系统下需要将WinIo.sys驱动文件添加数字签名。
2.注意WinIo.sys和WinIo.dll这两个文件的存放路径,如果路径不对,会导致初始化失败。
3.下载下来的WinIo文件中有一个DLL文件夹,如果发现初始化失败,我们可以打断点跟踪到dll里面去查看是哪里出了问题。例如,我在win8.1下使用的时候发现初始化失败,跟进去发现是OpenSCManager()函数返回了false,则是由于win8.1的用户权限设置导致的,通过查找响应的注册表位置即可初始化成功(参考网上的解决办法)。
4.使用WinIo的函数之前我们需要知道具体想要操作的是哪个端口,或者地址位置才行。
5.需要先将将DLL根据响应的版本进行编译(32位/64位)。
6.操作端口需要调用GetPortVal()/SetPortVal()函数,如果是操作具体的物理地址则需要调用GetPhyLong()/SetPhyLong()函数
下面是一个简单是实例
1 // WinIoDemo.cpp : 定义控制台应用程序的入口点。
4 #include "stdafx.h"
5 #include <Windows.h>
6 #include <iostream>
7 #include "winio.h"
8 #include <conio.h>
9 #include "GPIO_DLL.h"
10 using namespace std;
11
12 #define GPIO_PORT 0xFED10000 //假定的某个特定的物地址
17 int _tmain(int argc, _TCHAR* argv[])
18 {
19
bool bResult;
20
21
bResult = InitializeWinIo();
22
23
if (!bResult)
24 {
25
cout<<"error to initialize winio..."<<endl;
26
27
return -1;
28 }
29
else
30 {
32
unsigned long val;
33
unsigned long Data;
34
GetPhysLong((PBYTE)GPIO_PORT,&val);
35
printf("Current Value: %4x \n",val);
36
43
Data = val | 0x02;
//对bit1进行设定
45
46
printf("Current Value: %4x \n",Data);
47
48
bool br = SetPhysLong((PBYTE)GPIO_PORT,Data);
49
66
ShutdownWinIo();
67 }
68
printf("\nPress anykey to continue...");
69 _getch();
70
return 0;
71 }
Windows下对硬件端口的操作---WinIo库的使用