获取WinCE已加载驱动的信息
来源:互联网 发布:刘德华我知女人心电影 编辑:程序博客网 时间:2024/05/21 18:54
作者:SUKHOI27SMK
转自:http://blog.csdn.net/sukhoi27smk/article/details/8210507
//=====================================================================
//TITLE:
// WinCE驱动的动态加载
//AUTHOR:
// norains
//DATE:
// Monday 22- February-2010
//Environment:
// WINDOWS CE 5.0
//=====================================================================
WinCE驱动的调试,很多人的第一感觉就是:编写好DLL文件,接着在PB中添加相关注册表信息,然后将DLL文件包含进系统,最后生成系统,下载,调试。如果有误,那么依次按步骤重来。
其实这种繁琐的操作完全可以不必要,因为在WinCE下驱动是可以动态加载和卸载的。
驱动的加载和卸载非常简单,我们只需要如下两个函数:
- HANDLE ActivateDeviceEx(
- LPCWSTR lpszDevKey,
- LPCVOID lpRegEnts,
- DWORD cRegEnts,
- LPVOID lpvParam
- );
- BOOL DeactivateDevice(
- HANDLE hDevice
- );
前者是加载,后者是卸载。
我们首先来看一下加载函数。这函数很简单,lpszDevKey指向的是驱动信息在注册表的位置。比如,我之前文章所提到的虚拟串口的驱动的注册表信息如下:
[HKEY_LOCAL_MACHINE/Drivers/Builtin/VirtualSerial]
"Prefix"="VSP"
"Dll"="VirtualSerial.dll"
"Order"=dword:0
"Index"=dword:1
"Map_Port"="COM1:"
那么对于这个信息而言,lpszDevkey的取值为TEXT("Drivers//Builtin//VirtualSerial")。对于系统而言,驱动的Root Key为HKEY_LOCAL_MACHINE,故这里并不需要特别指出。换而言之,驱动的信息只能放置于HKEY_LOCAL_MACHINE,因为我们无法另外指定Root Key。
接下来再看看别的参数。lpRegEnts和cRegEnts是和BUS有关的,但我们接下来的例子并没有用上,所以这里直接可以忽略,直接赋值NULL即可。其实,如果不使用这两个形参的话,我们还可以选择ActivateDevice。
lpvParam指向的是传给驱动XXX_Init函数的形参,如果有特别需求,我们可以通过该指针进行传递。
函数功能很简单。我们写一个功能简单的驱动,来测试该函数是否有效。
驱动代码如下:
- DWORD g_dwParam = 0;
- std::wstring g_strContext;
- BOOL WINAPI DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
- {
- switch ( dwReason )
- {
- case DLL_PROCESS_ATTACH:
- break;
- }
- return TRUE;
- }
- DWORD FKE_Init(
- LPCTSTR pContext,
- LPCVOID lpvBusContext
- )
- {
- printf("FKE_Init !/r/n");
- if(pContext != NULL)
- {
- g_strContext = pContext;
- }
- if(lpvBusContext != NULL)
- {
- g_dwParam = *(reinterpret_cast<const DWORD *>(lpvBusContext));
- }
- return TRUE;
- }
- BOOL FKE_Deinit(
- DWORD dwContext
- )
- {
- printf("FKE_Deinit !/r/n");
- return TRUE;
- }
- DWORD FKE_Open(
- DWORD dwData,
- DWORD dwAccess,
- DWORD dwShareMode
- )
- {
- return TRUE;
- }
- BOOL FKE_Close(DWORD dwHandle)
- {
- return TRUE;
- }
- BOOL FKE_IOControl(
- DWORD dwHandle,
- DWORD dwIoControlCode,
- PBYTE pBufIn,
- DWORD dwBufInSize,
- PBYTE pBufOut,
- DWORD dwBufOutSize,
- PDWORD pBytesReturned
- )
- {
- return FALSE;
- }
- DWORD FKE_Read(DWORD dwHandle, LPVOID pBuffer, DWORD dwNumBytes)
- {
- std::vector<TCHAR> vtVal(MAX_PATH,0);
- _stprintf(&vtVal[0],TEXT("Context:%s/r/n Parameter:%d/r/n"),g_strContext.c_str(),g_dwParam);
- int iLen = _tcslen(&vtVal[0]);
- memcpy(pBuffer,&vtVal[0],iLen * 2);
- return iLen;
- }
- DWORD FKE_Write(DWORD dwHandle, LPCVOID pBuffer, DWORD dwNumBytes)
- {
- return 0;
- }
- DWORD FKE_Seek(DWORD dwHandle, long lDistance, DWORD dwMoveMethod)
- {
- return FALSE;
- }
- void FKE_PowerUp(void)
- {
- return;
- }
- void FKE_PowerDown(void)
- {
- return;
- }
代码意思很简单,就是在加载和卸载的时候,分别打印信息。然后还有两个全局变量,一个是g_strContext,用来保存成功加载时的注册表位置;另一个是g_dwParam,用来保存通过ActivateDeviceEx函数传递的第4个形参。而这两个全局变量的数值,之后我们可以通过ReadFile函数获得。只不过FKE_Read函数健壮性不高,没有判断缓冲区是否为空。但作为测试,还是够了。
驱动方面大致如此,我们再来实例看看如何加载驱动。因为驱动的加载涉及到注册表的写入,所以我这里直接采用了CReg类。关于该类的代码,详情可参见:(http://blog.csdn.net/norains/archive/2007/06/20/1659925.aspx)
我们先写注册表信息:
- #define DEV_KEY TEXT("Drivers//Builtin//FakeDriver")
- CReg reg;
- reg.Create(HKEY_LOCAL_MACHINE,DEV_KEY);
- reg.SetDW(TEXT("Order"),0);
- reg.SetDW(TEXT("Index"),1);
- reg.SetSZ(TEXT("Prefix"),TEXT("FKE"));
- reg.SetSZ(TEXT("Dll"),TEXT("//Windows//Driver.dll"));
稍微说一下注册表写入数值的意思。Order是加载的顺序,其实手工加载的话可以无视该字段。Index是打开时的序号,与此相关的还有Prefix,为驱动名。Dll则简单了,则是我们编译好的驱动的存放路径。
接下来就简单多了,我们加载驱动,然后传递一个DWORD的数值作为形参:
- DWORD dwParam = 89;
- HANDLE hd = ActivateDeviceEx(DEV_KEY,NULL,0,&dwParam);
- HANDLE hDriver = CreateFile(TEXT("FKE1:"),
- GENERIC_READ | GENERIC_READ,
- 0,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- std::vector<TCHAR> vtBuf(MAX_PATH);
- DWORD dwRead = 0;
- ReadFile(hDriver,&vtBuf[0],vtBuf.size(),&dwRead,NULL);
- CloseHandle(hDriver);
如果运行这段代码,你则会看到ReadFile之后,vtBuf则会存储到相应的数值。在我的平台上,某次运行时的数值如下:
Context:Driver/Active/37 Parameter:89
最后,就是卸载驱动。这个最简单,直接传递ActivateDeviceEx执行成功后返回的数值即可:
- 获取WinCE已加载驱动的信息
- 获取WinCE已加载驱动的信息
- 获取WinCE已加载驱动的信息
- 获取WinCE已加载驱动的信息
- WinCE驱动的动态加载
- WinCE驱动的动态加载
- WinCE驱动的动态加载
- WinCE驱动的动态加载
- WinCE驱动的动态加载
- 在ring3下列举系统中已加载的驱动模块的信息
- WINCE 显示驱动的加载过程
- WINCE流驱动的动态加载调试
- WINCE流驱动的动态加载调试
- wince驱动加载不成功的原因
- WINCE流驱动的自动加载
- WINCE流驱动的自动加载
- WinCE流驱动加载的控制
- WinCE流驱动加载的控制
- C# ArrayList类
- 中国名人排行榜2014年网络红人排行榜网络红人斌少
- Centos 6.3 添加中文输入法
- 据说,能把这个字符串题目做对的人,有,但寥寥无几!
- vim显示标签页的序号
- 获取WinCE已加载驱动的信息
- [转] C语言**位运算**终极剖析 分析的很详细
- Linux crontab命令学习
- 2013最吃香的技能:Java称霸、Android势头正猛
- AD9516
- CodeForce Round 219 Div2 E Watching Fireworks is Fun 单调队列DP
- C 语言中 setjmp 和 longjmp
- 大话WinCE与WinXP应用程序开发的差异性
- vim的常用命令