wince mysql驱动_WinCE驱动的动态加载

//=====================================================================

//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(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 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 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执行成功后返回的数值即可:

DeactivateDevice(hd);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值