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的帮助文档。