现在的位置: 首页 > 综合 > 正文

实战——驱动如何发消息通知APP动作?

2013年04月27日 ⁄ 综合 ⁄ 共 1316字 ⁄ 字号 评论关闭

CE中驱动和上层App的交互经常出现,最常用的方式是IOCTL,通过IOCTL的方式,上层App可以随时让驱动来做一些事情,然后将结果返回给App(当然也可以选择无返回参数),这个方式需要驱动导出XXX_IOContrl()函数,同时在该函数中需要修改或者添加所需的case来完成App指定的动作。当然,这个方式的发起者是App,底层驱动只是被动的接收并执行命令;那如果底层驱动是命令的发起者,该如何让App接收并执行命令呢?

这个时候就需要驱动发送消息给App,通知它去执行指定的命令了。

发送消息的方式有很多种,这里我只介绍我使用过的一个API,

BOOL SendNotifyMessage(
HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );

具体使用方式如下:

1.需要在驱动和App的头文件中定义如下相同的内容:

//Regist
Message
#define
WM_DRIVER_MESSAGE           
(WM_USER+999)
#define MESSAGEID_FROM_DRIVER   RegisterWindowMessage(L"WM_DRIVER_MESSAGE")

由于我发送的是HWND_BROADCAST类型的消息,所以必须用
RegisterWindowMessage来注册一个唯一的消息来供驱动和App交互

//Define Message type
typedef enum
{
    DRIVER_MESSAGE_USB_Attach =
0,              
   
DRIVER_MESSAGE_USB_Detach,                   
   
DRIVER_MESSAGE_POWERKEY_ShortPress,
   
DRIVER_MESSAGE_CHARGE_Done,               
} DRIVER_MESSAGE;

定义这些个消息类型是方便通过API的参数wParam把消息类型传递给App,这样的话我就只需要用
RegisterWindowMessage来注册一个Message,但却可以传递我定义的多个消息给App。

2.然后在驱动中需要发送消息的地方调用API并带上指定的消息类型即可:

SendNotifyMessage(HWND_BROADCAST, MESSAGEID_FROM_DRIVER, DRIVER_MESSAGE_CHARGE_Done, 0);

上层App中实现一个循环的消息检测机制,这样的话就能及时的收到驱动发送过来的消息,并根据消息类型来执行相应的命令了。

3.可能存在的bug:

用这种方式通知App来执行命令可能会引出一个bug:CE系统启动的时候,如果在驱动初始化的过程中恰好满足了SendNotifyMessage的条件而调用这个API给上层App发送消息的话,是会导致系统加载异常的。这是因为device.exe是在GWES.exe之前加载的,驱动给App发送消息的时候GWES还没有加载,从而会导致系统异常,所以需要我们注意规避一下可能存在的这个问题。

对于这个API更加详细的解释和说明,请参见PB的帮助文档。


抱歉!评论已关闭.