简单问题,你负责的系统出现了莫名其妙的异常,怎么办?换句话说,你有什么方法搞清楚问题的所在,进 而解决问题?对于这一类问题,我最关心的是系统内部的运行时状态,如果能搞清楚系统当前的问题状态,对找出问题的根源是很有帮助的。获取系统运行时状态肯 定要利用工具,在windows桌面系统上,简单的如windows自带的Task Manager, VC的Spy++,高级的如Sysinternals的Process Explorer/Process Monitor都是很有用的运行时分析工具。在Windows CE上,这类工具有Process Viewer,Kernel Tracker,以及我的Remote Process Explorer(这也是我写这个工具的目的之一)等。问题是,大多数基于Windows CE的设备的用户界面都是定制的,不像Windows桌面系统有个SHELL,可以随心所欲,什么程序都能跑。对于这类设备,需要找到一种办法,使得既能 在不需要时不增加系统负担,又能在需要的时候获取系统控制权来运行程序。
对于支持移动存储(如U盘、SD卡、CF卡等)的设备, 我觉得很好很强大的一个办法是autorun技术。实现方法也简单,思路是在这些存储设备上放一个autorun.exe,系统后台有线程侦测卡的插入, 发现卡上autorun.exe就把它运行起来。非常类似于CD/DVD的autorun技术,很简单但很实用。Windows Mobile直接支持了AUTORUN,其实Windows CE上实现起来也很简单:随便写个driver或者service,系统启动时自动运行,等待各种存储卡的插拔事件,检测卡上某个目录是否存在 autorun.exe,然后把autorun.exe运行起来。
实现时,首先要在初始化时创建一个消息队列来等待系统的设备插拔时间通知:
struct MYDEV {
union {
DEVDETAIL dev;
BYTE buf[sizeof(DEVDETAIL)+sizeof(TCHAR)*MAX_DEVCLASS_NAMELEN];
};
};
MSGQUEUEOPTIONS msgOptions;
HANDLE hq, hn;
// Initialize file system notification stuff
memset(&msgOptions, 0, sizeof(msgOptions));
msgOptions.dwSize = sizeof(msgOptions);
msgOptions.dwFlags = 0;
msgOptions.dwMaxMessages = 20;
msgOptions.cbMaxMessage = sizeof(MYDEV);
msgOptions.bReadAccess = TRUE;
hq = CreateMsgQueue(NULL, &msgOptions);
if (hq)
{
hn = RequestDeviceNotifications(&FATFS_MOUNT_GUID, hq, TRUE);
if (hn)
SetEvent(hq);
}然后在线程循环中,用WaitForSingleObject等待并处理该事件:
if (WAIT_OBJECT_0 == WaitForSingleObject(hq, INFINITE))
{
DWORD dwBytesReturn;
DWORD flags;
MYDEV detail;
while (ReadMsgQueue(hq, &detail, sizeof(detail), &dwBytesReturn, 0, &flags))
{
if (detail.dev.fAttached && IsEqualGUID(FATFS_MOUNT_GUID, detail.dev.guidDevClass))
{
RETAILMSG(1, (TEXT("Found storage device: %s/r/n"), detail.dev.szName));
//HandleMountedStorageDevice(detail.dev.szName);
}
}
}几个关键的地方是,
- 定义一个MYDEV结构接收消息;
- 用CreateMsgQueue创建消息队列以接收系统消息;
- 用RequestDeviceNotifications接收FATFS_MOUNT_GUID类型消息,这意味着所有FAT文件系统mount和unmount的消息都会得到通知(U盘和各种存储卡一般都使用FAT文件系统);
- 用WaitForSingleObject等待通知,对系统性能没有额外负担。如果有多个事件,可以用WaitForMultipleObjects,如果还有windows消息要处理(比如在主线程循环中),可以用MsgWaitForMultipleObjects;
- 等到后用ReadMsgQueue读取消息,并用IsEqualGUID判断消息类型然后处理。
本文介绍了在Windows CE设备上利用Autorun技术进行运行时状态分析的方法,特别是在移动存储设备如U盘、SD卡、CF卡等上的应用。通过创建消息队列和监听设备插拔事件,当检测到autorun.exe时自动运行,以此提供了一种在不增加系统负担情况下获取系统控制权的解决方案。文中详细阐述了实现过程,包括创建消息队列、接收设备事件以及处理 Autorun 执行的步骤。


union
9149

被折叠的 条评论
为什么被折叠?



