在一些项目中,系统需要实时监测U盘或SD卡的插入拔出。当文件系统加载成功后通知特定应用程序,启动自动播放功能。在U盘或其他外部存储设备移除时,也需要立即通知相应的程序,停止访问这些设备,如播放其中的音视频文件,以免程序出错。
我们可以使用WinCE设备管理器提供的Device Interface Notification来实现这个功能,参考代码如下。
DWORD WINAPI ThreadFun(LPVOID lpParameter)
{
HANDLE ph[MAXIMUM_WAIT_OBJECTS];
HANDLE phMsgQueue[MAXIMUM_WAIT_OBJECTS - 1 ];
HANDLE phDevNotif[MAXIMUM_WAIT_OBJECTS - 1 ];
MSGQUEUEOPTIONS msgopts;
GUID guid[] = {BLOCK_DRIVER_GUID, FSD_MOUNT_GUID};
DWORD dwCount;
BYTE pDevBuf[ sizeof (DEVDETAIL) + MAX_DEVCLASS_NAMELEN * sizeof (TCHAR)] = { 0 };
DEVDETAIL * pd = (DEVDETAIL * )pDevBuf;
ghExitThread = CreateEvent(NULL, FALSE, FALSE, NULL);
ph[ 0 ] = ghExitThread;
dwCount = sizeof (guid) / sizeof (GUID);
for (DWORD i = 0 ; i < dwCount; i ++ )
{
memset( & msgopts, 0 , sizeof (msgopts));
msgopts.dwFlags = 0 ;
msgopts.dwSize = sizeof (msgopts);
msgopts.dwMaxMessages = 0 ;
msgopts.cbMaxMessage = sizeof (pDevBuf);
msgopts.bReadAccess = TRUE;
phMsgQueue[i] = CreateMsgQueue(NULL, & msgopts);
phDevNotif[i] = RequestDeviceNotifications(guid + i, phMsgQueue[i], TRUE);
ph[i + 1 ] = phMsgQueue[i];
}
while ( 1 )
{
DWORD dwSize;
DWORD dwFlags;
DWORD dwWait;
DWORD dwQueue;
dwWait = WaitForMultipleObjects(dwCount + 1 , ph, FALSE, INFINITE);
if ((dwWait <= WAIT_OBJECT_0) || (dwWait >= (WAIT_OBJECT_0 + dwCount + 1 )))
{
break ;
}
dwQueue = (dwWait - WAIT_OBJECT_0) - 1 ;
while (ReadMsgQueue(phMsgQueue[dwQueue], pd, sizeof (pDevBuf), & dwSize, 1 , & dwFlags))
{
if (GUID_ISEQUAL(pd -> guidDevClass, BLOCK_DRIVER_GUID))
{
printf( " \r\nDEV:%S %s " , pd -> szName, pd -> fAttached ? " Add! " : " Removed! " );
if (pd -> fAttached)
{
Sleep( 10 );
printf( " \r\nOpenStore! " );
HANDLE h = OpenStore(pd -> szName);
STOREINFO si;
memset( & si, 0 , sizeof (si));
si.cbSize = sizeof (si);
printf( " \r\nGetStoreInfo! " );
GetStoreInfo(h, & si);
printf( " \r\n%S %x " , si.szStoreName, si.dwDeviceType);
CloseHandle(h);
}
}
else if (GUID_ISEQUAL(pd -> guidDevClass, FSD_MOUNT_GUID))
{
printf( " \r\nFSD:%S %s " , pd -> szName, pd -> fAttached ? " Add! " : " Removed! " );
}
Sleep( 1 );
}
}
for (DWORD i = 0 ; i < dwCount; i ++ )
{
StopDeviceNotifications(phDevNotif[i]);
CloseMsgQueue(phMsgQueue[i]);
}
CloseHandle(ghExitThread);
return 0 ;
}
{
HANDLE ph[MAXIMUM_WAIT_OBJECTS];
HANDLE phMsgQueue[MAXIMUM_WAIT_OBJECTS - 1 ];
HANDLE phDevNotif[MAXIMUM_WAIT_OBJECTS - 1 ];
MSGQUEUEOPTIONS msgopts;
GUID guid[] = {BLOCK_DRIVER_GUID, FSD_MOUNT_GUID};
DWORD dwCount;
BYTE pDevBuf[ sizeof (DEVDETAIL) + MAX_DEVCLASS_NAMELEN * sizeof (TCHAR)] = { 0 };
DEVDETAIL * pd = (DEVDETAIL * )pDevBuf;
ghExitThread = CreateEvent(NULL, FALSE, FALSE, NULL);
ph[ 0 ] = ghExitThread;
dwCount = sizeof (guid) / sizeof (GUID);
for (DWORD i = 0 ; i < dwCount; i ++ )
{
memset( & msgopts, 0 , sizeof (msgopts));
msgopts.dwFlags = 0 ;
msgopts.dwSize = sizeof (msgopts);
msgopts.dwMaxMessages = 0 ;
msgopts.cbMaxMessage = sizeof (pDevBuf);
msgopts.bReadAccess = TRUE;
phMsgQueue[i] = CreateMsgQueue(NULL, & msgopts);
phDevNotif[i] = RequestDeviceNotifications(guid + i, phMsgQueue[i], TRUE);
ph[i + 1 ] = phMsgQueue[i];
}
while ( 1 )
{
DWORD dwSize;
DWORD dwFlags;
DWORD dwWait;
DWORD dwQueue;
dwWait = WaitForMultipleObjects(dwCount + 1 , ph, FALSE, INFINITE);
if ((dwWait <= WAIT_OBJECT_0) || (dwWait >= (WAIT_OBJECT_0 + dwCount + 1 )))
{
break ;
}
dwQueue = (dwWait - WAIT_OBJECT_0) - 1 ;
while (ReadMsgQueue(phMsgQueue[dwQueue], pd, sizeof (pDevBuf), & dwSize, 1 , & dwFlags))
{
if (GUID_ISEQUAL(pd -> guidDevClass, BLOCK_DRIVER_GUID))
{
printf( " \r\nDEV:%S %s " , pd -> szName, pd -> fAttached ? " Add! " : " Removed! " );
if (pd -> fAttached)
{
Sleep( 10 );
printf( " \r\nOpenStore! " );
HANDLE h = OpenStore(pd -> szName);
STOREINFO si;
memset( & si, 0 , sizeof (si));
si.cbSize = sizeof (si);
printf( " \r\nGetStoreInfo! " );
GetStoreInfo(h, & si);
printf( " \r\n%S %x " , si.szStoreName, si.dwDeviceType);
CloseHandle(h);
}
}
else if (GUID_ISEQUAL(pd -> guidDevClass, FSD_MOUNT_GUID))
{
printf( " \r\nFSD:%S %s " , pd -> szName, pd -> fAttached ? " Add! " : " Removed! " );
}
Sleep( 1 );
}
}
for (DWORD i = 0 ; i < dwCount; i ++ )
{
StopDeviceNotifications(phDevNotif[i]);
CloseMsgQueue(phMsgQueue[i]);
}
CloseHandle(ghExitThread);
return 0 ;
}