windows下开发驱动并不难
/********************此文可以被转发,但请转发者保留作者的署名权
****李浩
****msn:lihao_nx@hotmail.com
****
****email:lihaoyxj@gmail.com
我在前些年一直写应用类软件,由于环境不具备特殊要求的环境,故从1997年使用WIN95到99年多少明白一点驱动的概念开始,对驱动这个东西是一个不敢去思考的存在.
****李浩
****msn:lihao_nx@hotmail.com
****
****email:lihaoyxj@gmail.com
****出处:lihaoyxj.cublog.cn
**** www.cnblogs.com/lihaoyxj
我在前些年一直写应用类软件,由于环境不具备特殊要求的环境,故从1997年使用WIN95到99年多少明白一点驱动的概念开始,对驱动这个东西是一个不敢去思考的存在.
在前一段时间开发时,需要用到一个键盘类的驱动,故想学习并进行一个键盘驱动的开发.
首先,还是要进行一个开发环境搭建.
1. windows xp
2. vs2008
3. winxp ddk
4. http://ddkwizard.assarbad.net/下载ddkwizrd
5. 将ddkbuild.cmd或ddkbuild.bat拷贝到winddk"ver,如我的为c:"winddk"3790.1830下
6. 在vs2008的vc目录环境中executable files中把刚才的c:"winddk加入进来
按以上的步骤,你在创建一个new project时可以看到有ddk project的项目了.
我上传的包为,我第一次使用以上的环境按别人的方法及部分源码做出的驱动版hello,world
|
现在有了环境和程序,那么就需要在你的电脑上进行测试了
其次,驱动的调试环境,我强烈推荐你用VM及snapshot后进行.还需要以下几个软件.
1.debugview 查看调试信息用
2.devicetree 查看驱动的device细节
3.OSRLOADER 非常不错的即时加载及启动驱动的工具
再次,进行以上项目的调试,源码中有非常清楚的注释,就不过多说源码.
1. 编译程序会在Driver1"Driver1"objchk_wnet_x86"i386"下有driver1.sys
2. 将以上提到的三个工具与driver1.sys 传到VM中的XP上
3. 用OSRLOADER 加载生成的driver1.sys并启动它,就可以用devicetree看到helloworld这个驱动了.
刚说了是要调试环境,怎么没有调试啊?不要急,在这里是因为helloworld这个驱动别的程序不会访问的,自然就不会出调试信息了,那么为了访问helloworld,则需要再开发一个调用驱动的程序了
由于只有一个文件,是命令行下程序,所以就把源作者的源码发布出来
#define DEBUGMSG
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#include <winioctl.h>
#include <stdio.h>
#define DEVICE_HELLO_INDEX 0x860
#define START_HELLPWORLD CTL_CODE(FILE_DEVICE_UNKNOWN,DEVICE_HELLO_INDEX,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define STOP_HELLPWORLD CTL_CODE(FILE_DEVICE_UNKNOWN,DEVICE_HELLO_INDEX+1,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define STOP_HELLPWORLD CTL_CODE(FILE_DEVICE_UNKNOWN,DEVICE_HELLO_INDEX+1,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define erron GetLastError()
#define MY_DEVICE_NAME """"".""HelloWorld"
#define MY_DEVICE_START "-start"
#define MY_DEVICE_STOP "-stop"
#define MY_DEVICE_STOP "-stop"
BOOL DriverControl (TCHAR *Maik);
void Usage (TCHAR *Paramerter);
int main (int argc,TCHAR *argv[])
{
if (argc!=2)
{
Usage(argv[0]);
return 0;
}
int main (int argc,TCHAR *argv[])
{
if (argc!=2)
{
Usage(argv[0]);
return 0;
}
if (strcmpi(argv[1],MY_DEVICE_START)==0 || strcmpi(argv[1],MY_DEVICE_STOP)==0)
DriverControl(argv[1]);
else
{
Usage(argv[0]);
return 0;
}
DriverControl(argv[1]);
else
{
Usage(argv[0]);
return 0;
}
return 0;
}
BOOL DriverControl (TCHAR *Maik)
{
HANDLE hDevice=NULL; //设备句柄
DWORD RetBytes=0;
}
BOOL DriverControl (TCHAR *Maik)
{
HANDLE hDevice=NULL; //设备句柄
DWORD RetBytes=0;
//获得设备句柄
hDevice=CreateFile(MY_DEVICE_NAME,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
hDevice=CreateFile(MY_DEVICE_NAME,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hDevice==INVALID_HANDLE_VALUE)
{
#ifdef DEBUGMSG
printf("CreateFile() GetLastError reports %d"n",erron);
#endif
return FALSE;
}
{
#ifdef DEBUGMSG
printf("CreateFile() GetLastError reports %d"n",erron);
#endif
return FALSE;
}
//启动
if (strcmpi(Maik,MY_DEVICE_START)==0)
{
//传递启动的I/O控制代码
if (!(DeviceIoControl(hDevice,START_HELLPWORLD,NULL,0,NULL,0,&RetBytes,NULL)))
{
#ifdef DEBUGMSG
printf("DeviceIoControl() GetLastError reports %d"n",erron);
#endif
CloseHandle(hDevice);
return FALSE;
}
}
if (strcmpi(Maik,MY_DEVICE_START)==0)
{
//传递启动的I/O控制代码
if (!(DeviceIoControl(hDevice,START_HELLPWORLD,NULL,0,NULL,0,&RetBytes,NULL)))
{
#ifdef DEBUGMSG
printf("DeviceIoControl() GetLastError reports %d"n",erron);
#endif
CloseHandle(hDevice);
return FALSE;
}
}
//停止
if (strcmpi(Maik,MY_DEVICE_STOP)==0)
{
//传递停止的I/O控制代码
if (!(DeviceIoControl(hDevice,STOP_HELLPWORLD,NULL,0,NULL,0,&RetBytes,NULL)))
{
#ifdef DEBUGMSG
printf("DeviceIoControl() GetLastError reports %d"n",erron);
#endif
CloseHandle(hDevice);
return FALSE;
}
}
if (strcmpi(Maik,MY_DEVICE_STOP)==0)
{
//传递停止的I/O控制代码
if (!(DeviceIoControl(hDevice,STOP_HELLPWORLD,NULL,0,NULL,0,&RetBytes,NULL)))
{
#ifdef DEBUGMSG
printf("DeviceIoControl() GetLastError reports %d"n",erron);
#endif
CloseHandle(hDevice);
return FALSE;
}
}
if (hDevice)
CloseHandle(hDevice); //关闭句柄
CloseHandle(hDevice); //关闭句柄
return TRUE;
}
void Usage (TCHAR *Paramerter)
{
fprintf(stderr,"============================================================================"n"
" 驱动版Hello World"n"
"作者:dahubaobao[EST]"n"
"主页:www.eviloctal.com or www.ringz.org"n"
"邮件:[email]dahubaobao@eviloctal.com[/email]"n"
"OICQ:382690"n"n"
"%s -start"t启动"n"
"%s -stop "t停止"n"n"
"本程序只是用做代码交流,如有错误,还请多多包含!"n"
"============================================================================"n"
,Paramerter,Paramerter);
}
}
void Usage (TCHAR *Paramerter)
{
fprintf(stderr,"============================================================================"n"
" 驱动版Hello World"n"
"作者:dahubaobao[EST]"n"
"主页:www.eviloctal.com or www.ringz.org"n"
"邮件:[email]dahubaobao@eviloctal.com[/email]"n"
"OICQ:382690"n"n"
"%s -start"t启动"n"
"%s -stop "t停止"n"n"
"本程序只是用做代码交流,如有错误,还请多多包含!"n"
"============================================================================"n"
,Paramerter,Paramerter);
}
在编译后,假如为calldriver.exe,那么将它也传到刚才的VM环境中,然后先打开,debugview,然后运行calldriver.exe程序
calldriver -start
calldriver -stop
再看看debugview中,通过DbgPrint在驱动程序中打印的消息就出来了.
因为是熟悉驱动开发,引用了别人的源代码,请谅解。