zoukankan      html  css  js  c++  java
  • WinCE 系统下移动存贮设备Storage 的拔插检测

    今天在编程检测 Storage(SD/USB) 时,使用了一个消息:WM_DEVICECHANGE 来检测,测试了一下插入/拔出 Storage 设备时确实可以接收到消息。
    但后继的处理出现问题:在 Storage 设备拔出时,立刻调用 FindFirstStore/FindNextStore 和 FindFirstPartition/FindNextPartition 时正常;
    但在 Storage 设备插入时,立刻调用 FindFirstStore/FindNextStore 和 FindFirstPartition/FindNextPartition 未检测到刚插入的 Storage 设备的目录(盘符)。
    单步测试发现,只要在首次调用 FindFirstStore 时停一会,就正常。说明在接收到 WM_DEVICECHANGE 消息时不能立刻扫描,需要等待一会。
    看了一下公司其它项目对 WM_DEVICECHANGE 消息的处理,都是采用延时如 200ms 来处理。
     
    延时处理,个人认为不是好的办法。因为:
    (1) 延时的时间不好确认
    (2)在 Storage 设备拔出后,如果在延时的时间内、且设备已经拔出时出现文件操作,较难处理。
     
    除了处理设备的插入/拔出的硬件检测消息外,是否有其它办法来检测 Storage 设备的插入/拔出?
    答案是肯定的。可以采用文件系统的 MOUNT/UNMOUNT 消息来处理。
     
    请看以下示例代码:
     1 #include "pnp.h"  
     2 #include "storemgr.h"  
     3   
     4 #define DEVICE_QUEUE_MAX_SIZE 3  
     5   
     6 static BOOL gbExitDetectThread = FALSE;  
     7   
     8 union BufferPlusDevDetail  
     9 {  
    10     DEVDETAIL DevDetail;  
    11     BYTE byBuffer[sizeof(DEVDETAIL) + MAX_DEVCLASS_NAMELEN * sizeof(TCHAR)];  
    12 };  
    13   
    14 DWORD DevicePlugDetectThread(LPVOID lpPara)  
    15 {  
    16     DWORD dwObjectRet = 0;  
    17     MSGQUEUEOPTIONS msgQInfo =   
    18     {  
    19         sizeof(MSGQUEUEOPTIONS),  
    20         MSGQUEUE_ALLOW_BROKEN,   
    21         DEVICE_QUEUE_MAX_SIZE,  
    22         sizeof(BufferPlusDevDetail),  
    23         TRUE  
    24     };  
    25     DWORD dwMsgSize = 0;  
    26     DWORD dwAlert = 0;  
    27   
    28     HANDLE hStorageMsgQueue = CreateMsgQueue(NULL, &msgQInfo);  
    29     if (NULL == hStorageMsgQueue)  
    30     {  
    31         return FALSE;  
    32     }  
    33     // request notification  
    34     HANDLE hStorageNotify = RequestDeviceNotifications(&FATFS_MOUNT_GUID, hStorageMsgQueue, FALSE);  
    35     if(NULL == hStorageNotify)  
    36     {  
    37         return FALSE;  
    38     }  
    39   
    40     while(1)  
    41     {  
    42         if(gbExitDetectThread)  
    43         {  
    44             break;  
    45         }  
    46         dwObjectRet = WaitForSingleObject(hStorageMsgQueue,1000);  
    47         if(WAIT_OBJECT_0 == dwObjectRet)  
    48         {  
    49             BufferPlusDevDetail DevBuff = {0};  
    50             if (ReadMsgQueue(hStorageMsgQueue, &DevBuff, sizeof(DevBuff), &dwMsgSize, 0, &dwAlert))  
    51             {  
    52                 BOOL bAttached = DevBuff.DevDetail.fAttached;  
    53                 CString csStorageName = DevBuff.DevDetail.szName;  
    54                 RETAILMSG(1,(L"Storage:: received %s message: %s!
    ",0 == bAttached ? L"unmount" : L"mount",csStorageName));  
    55   
    56                 COPYDATASTRUCT cs;  
    57                 TCHAR tcStorage[MAX_PATH];  
    58   
    59                 ZeroMemory(tcStorage,sizeof(TCHAR) * MAX_PATH);  
    60                 wsprintf(tcStorage,L"%s",csStorageName);  
    61                 cs.dwData = 0x5050;  
    62                 cs.cbData = sizeof(TCHAR) * wcslen(tcStorage);  
    63                 cs.lpData = tcStorage;  
    64                 SendMyMsgToAgent(WM_COPYDATA,bAttached,(LPARAM)&cs);  
    65             }  
    66         }  
    67         else if(WAIT_TIMEOUT == dwObjectRet)  
    68         {  
    69         }  
    70     }  
    71   
    72     StopDeviceNotifications(hStorageNotify);  
    73     CloseHandle(hStorageNotify);  
    74   
    75     return TRUE;  
    76 }  
    77   
    78 // 调用示例,直接开启线程。代码如下:  
    79 CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)DevicePlugDetectThread, NULL, 0, NULL);  
  • 相关阅读:
    SQL SERVER的检查点checkpoint
    MySQL备份说明
    声明对象和创建对象的区别
    getParameter的用法总结
    Jsp的九大对象,七大动作,三大指令
    为什么内部类访问的外部变量需要使用final修饰
    java synchronized详解
    网上选课系统需求说明书
    第三次作业
    第二次作业
  • 原文地址:https://www.cnblogs.com/91program/p/5205061.html
Copyright © 2011-2022 走看看