wince下流式驱动的编写

       WinCE的设备驱动程序都是简单的DLL,然后导出特定的入口函数。驱动程序不是由与驱动打交道的应用程序直接载入而是由设备管理器在载入的(在Wince 5.0Device.exe加载的,在Wince6.0是由uDevice.exe加载的)。

       Wince下的驱动大多数是流式设备驱动,一个流式驱动会暴露12个外部入口函数。设备管理器会调用它们与驱动程序交互。

列举一下每种入口函数的作用:

XXX_Init              初始化设备,在设备被加载时调用

XXX_PreDeinit   通知程序把设备句柄设置无效,在设备即将卸载时调用。

XXX_Deinit          释放设备,在设备被卸载时调用

XXX_Open           打开设备进行读、写,应用程序调用CreateFile打开设备时调用

XXX_Close         关闭设备,应用程序调用CloseHandle关闭设备时调用

XXX_PreClose      通知驱动程序把打开的句柄设置无效

XXX_Read           从设备中读取数据,应用程序调用ReadFile时调用

XXX_Write           向设备中写入数据,应用程序调用WriteFile时调用

XXX_Seek            移动设备中的数据,应用程序调用SetFilePointer时调用

XXX_IOControl    对设备发送控制命令,应用程序调用DeviceIOControl时调用

XXX_PowerUp   在系统恢复挂起前被调用

XXX_PowerDown 在系统挂起前调用

我们了解了流式驱动所有外部入口函数作用,现在就可以开始尝试着写一个我们自己的驱动。

1、  VS2005定制一个WINCE系统的工程中建立一个Subprojects工程, 选择中“Subprojects”点击右键->Add New Subproject…”弹出对话框如图:

wince下流式驱动的编写_第1张图片

 

选择“WCE Dynamic – Link Library”在Subproject name中输入工程名,点击“Finish”就好了。

2Subproject工程建立后,编译器自动帮你生成一些配置文件如图:

wince下流式驱动的编写_第2张图片

 

3、新建一个CPP文件,编写驱动代码。

 

 

下面我自己写的一个驱动代码:

#include<windows.h> #include<tchar.h> //Globals TCHAR g_Buf[MAX_PATH] ={TEXT("MyDrv")}; HINSTANCE hInst; BOOL WINAPI DllMain ( HANDLE hinstDLL, DWORD dwReason,LPVOID lpvReserved) { hInst = (HINSTANCE) hinstDLL; switch(dwReason) { } return TRUE; } DWORD DRV_Open( DWORD hDeviceContext,//设备上下文,由DRV_init()函数创建 DWORD AccessCode, //设备的访问模式,从Createfile()函数传入 DWORD ShareMode //设备的共享模式,从Createfile()函数传入 ) { RETAILMSG(TRUE,(TEXT("[+DRV_Open]/r/n"))); // //Add code // RETAILMSG(TRUE,(TEXT("[-DRV_Open]/r/n"))); return TRUE; } BOOL DRV_Close( DWORD hOpenContext //设备打开的上下文,由DRV_Open()函数返回 ) { RETAILMSG(TRUE,(TEXT("[+DRV_Close]/r/n"))); // //Add code // RETAILMSG(TRUE,(TEXT("[-DRV_Close]/r/n"))); return TRUE; } DWORD DRV_Init( LPCSTR pContext, //字符串,指向注册表中记录活动驱动程序的键 LPCVOID lpvBusContext //ActivateDeviceEx()函数的第四个参数,VOID指针 ) { RETAILMSG(TRUE,(TEXT("[+DRV_Init]/r/n"))); // //Add code // RETAILMSG(TRUE,(TEXT("[-DRV_Init]/r/n"))); return TRUE; } BOOL DRV_Deinit( DWORD hDeviceContext //DRV_Init()函数返回的设备上下文 ) { RETAILMSG(TRUE,(TEXT("[+DRV_Deinit]/r/n"))); // //Add code // RETAILMSG(TRUE,(TEXT("[-DRV_Deinit]/r/n"))); return TRUE; } DWORD DRV_Read( DWORD hOpenContext,//DRV_Open()返回的设备打开的上下文 LPVOID pBuffer, //输出,输出缓冲区的指针,读取的数据会被放在改缓冲区内 DWORD Count //要读取的字节数 ) { RETAILMSG(TRUE,(TEXT("[+DRV_Read]/r/n"))); // //Add code // int iLen = _tcslen(g_Buf); memcpy(pBuffer,g_Buf,iLen *2); RETAILMSG(TRUE,(TEXT("[-DRV_Read]/r/n"))); return TRUE; } DWORD DRV_Write( DWORD hOpenContext,//DRV_Open()返回的设备打开的上下文 LPVOID pBuffer, //输入,输入缓冲区的指针,输入的数据会被放在改缓冲区内 DWORD Count //要写入的字节数 ) { RETAILMSG(TRUE,(TEXT("[+DRV_Write]/r/n"))); // //Add code // if(Count >= MAX_PATH) { RETAILMSG(TRUE,(TEXT("[Error]:DRV_Write Write data error!/r/n"))); return FALSE; } memset(g_Buf,0,MAX_PATH * 2); memcpy(g_Buf,pBuffer,Count *2); RETAILMSG(TRUE,(TEXT("[-DRV_Write]/r/n"))); return TRUE; } DWORD DRV_Seek( DWORD hOpenContext,//DRV_Open()返回的设备打开的上下文 long Amount, //要移动的距离,负数表示向前移,正数为向后移 WORD Type //移动的相对位置,有FILE_BEGIN、FILE_CURRENT和FILE_END ) { RETAILMSG(TRUE,(TEXT("[+DRV_Seek]/r/n"))); // //Add code // RETAILMSG(TRUE,(TEXT("[-DRV_Seek]/r/n"))); return TRUE; } BOOL DRV_IOControl( DWORD hOpenContext,//DRV_Open()返回的设备打开上下文 DWORD dwCode, //要发送的控制码,一个32位无符号数 PBYTE pBufIn, //输入,指向输入缓冲区的指针 DWORD dwLenIn, //输入缓冲区的长度 PBYTE pBufOut, //输出,指向输出缓冲区的指针 DWORD dwLenOut, //输出缓冲区的长度 PDWORD pdwActualOut//输出,设备实际输出字符数 ) { RETAILMSG(TRUE,(TEXT("[+DRV_IOControl]/r/n"))); // //Add code // RETAILMSG(TRUE,(TEXT("[-DRV_IOControl]/r/n"))); return TRUE; } BOOL DRV_PreClose( DWORD hOpenContext //设备打开的上下文 ) { RETAILMSG(TRUE,(TEXT("[+DRV_PreClose]/r/n"))); // //Add code // RETAILMSG(TRUE,(TEXT("[-DRV_PreClose]/r/n"))); return TRUE; } BOOL DRV_PreDeinit( DWORD hDeviceContext //设备的上下文 ) { RETAILMSG(TRUE,(TEXT("[+DRV_PreDeinit]/r/n"))); // //Add code // RETAILMSG(TRUE,(TEXT("[-DRV_PreDeinit]/r/n"))); return TRUE; } void DRV_PowerUp( DWORD dwContext //由DRV_Init()返回的设备的上下文句柄 ) { RETAILMSG(TRUE,(TEXT("[+DRV_PowerUp]/r/n"))); // //Add code // RETAILMSG(TRUE,(TEXT("[-DRV_PowerUp]/r/n"))); } void DRV_PowerDown( DWORD dwContext //由DRV_Init()返回的设备的上下文句柄 ) { RETAILMSG(TRUE,(TEXT("[+DRV_PowerDown]/r/n"))); // //Add code // RETAILMSG(TRUE,(TEXT("[-DRV_PowerDown]/r/n"))); }

 

MyDriver.def

LIBRARY     MYDRIVE

EXPORTS
	DRV_Init             
	DRV_PreDeinit   
	DRV_Deinit         
	DRV_Open           
	DRV_Close       
	DRV_PreClose     
	DRV_Read         
	DRV_Write          
	DRV_Seek           
	DRV_IOControl   
	DRV_PowerUp   
	DRV_PowerDown 


 

现在我们可以测试一下驱动程序,测试代码如下:

// fff.cpp : Defines the entry point for the console application. // #include <windows.h> #include<tchar.h> int _tmain(int argc, _TCHAR* argv[]) { TCHAR ReadBuf[MAX_PATH] ={0}; TCHAR WriteBuf[MAX_PATH ]={TEXT("Write new data!")}; DWORD dwNumber = 0; HANDLE hDevice = CreateFile(TEXT("DRV1:"),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(hDevice) { ReadFile(hDevice,ReadBuf,MAX_PATH,&dwNumber,NULL); //ReadBuf中的内容为:“MyDrv” WriteFile(hDevice,WriteBuf,MAX_PATH - 1,&dwNumber,NULL); ReadFile(hDevice,ReadBuf,MAX_PATH,&dwNumber,NULL); //ReadBuf中的内容为:“Write new data!” CloseHandle(hDevice); } return 0; }

注意:我们还需要修改一下.bib文件,将

MODULES

XXX.dll  $(_FLATRELEASEDIR)/MyDrv.dll               NK

 

改为:

MODULES

XXX.dll  $(_FLATRELEASEDIR)/MyDrv.dll               NK  K

 

至于为什么,请查阅http://blog.csdn.net/norains/archive/2010/11/10/6000519.aspx

 

 

 

 

 

你可能感兴趣的:(File,null,Path,library,WinCE,winapi)