(程序运行在装有卡巴斯基的机器上,我总怀疑和它有点关系)我在程序中,用 “盘符mask变化”和“WM_DEVICECHANGE”判断U盘插入后,
1 马上获取U盘vidpid 、序列号等信息。
2 还有 调用函数 fun1 根据盘符 CreateFile 后, ReadFile 了 512字节 : ... 判断 CreateFile 返回 ERROR_INVALID_HANDLE 后,会返回FALSE
... 根据读取出来的512字节,判断是否满足条件,不满足条件,返回FALSE;
... 满足条件,返回TRUE;我有一个U盘,肯定了其一定不满足条件。
可是,在使用过程中,有时,走的分支是 “不满足条件”那条。
那最有可能的就是 CreateFile 失败!我很想知道,是否是:
在我CreateFile的时刻,U盘在独占或者什么其他我不知道的状态,所以返回 ERROR_INVALID_HANDLE ?
而我又只调用一次 fun1 导致的? …
貌似是个经验问题,请大侠们指教!
1 马上获取U盘vidpid 、序列号等信息。
2 还有 调用函数 fun1 根据盘符 CreateFile 后, ReadFile 了 512字节 : ... 判断 CreateFile 返回 ERROR_INVALID_HANDLE 后,会返回FALSE
... 根据读取出来的512字节,判断是否满足条件,不满足条件,返回FALSE;
... 满足条件,返回TRUE;我有一个U盘,肯定了其一定不满足条件。
可是,在使用过程中,有时,走的分支是 “不满足条件”那条。
那最有可能的就是 CreateFile 失败!我很想知道,是否是:
在我CreateFile的时刻,U盘在独占或者什么其他我不知道的状态,所以返回 ERROR_INVALID_HANDLE ?
而我又只调用一次 fun1 导致的? …
貌似是个经验问题,请大侠们指教!
这句话说的不太准确, 修正一下:我的fun1原型:
BOOL fun1(TCHAR drive, DWORD& dwTime);当 ReadFile成功后, 把指定的 数组元素,赋值给 dwTime
我之所以肯定,是因为,该U盘的那个位置的值是固定的非0值,而我写U盘 卷 header 的时候,这个位置一定是0,不是0的话,就代表,没写进去。所以,从这点,判断其 不满足条件。
BOOL ret;
ret = fun1(drive[0], dwtime);正常返回FALSE的时候,dwTime应该是个非0值,
返回TRUE的时候,才是0值 ,
可是,我发这个帖子的原因,就是返回 FALSE 的时候,dwTime 等于 0所以,我判断,应该是 ReadFile 之前 的 CreateFile 的时候,出了问题
(我承认,这样的代码设计 确实不好。)哎,应该是说明白了。谢谢答复!
很疑惑,因为我连续调用三次,貌似就没问题了
BOOL GetUsbData(TCHAR chDriveLetter, DWORD &dwTime)
{
CHAR szBuffer[512];
HANDLE hDisk;
int iThird = 0; CString sLogicalDisk;
sLogicalDisk = _T("\\\\.\\" + chDriveLetter + ":"); hDisk = CreateFile (sLogicalDisk,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hDisk == INVALID_HANDLE_VALUE)
{
return FALSE; //第 1 处
} int iRes;
ULONG bytesread; SetFilePointer(hDisk, 0, NULL, FILE_BEGIN);
iRes = ReadFile(hDisk, szBuffer, 512, &bytesread, NULL);
if(( iRes != 1 ) | ( bytesread != 512))
{
CloseHandle(hDisk);
return FALSE; //第 2 处
} memcpy(((PCHAR)&dwTime), &szBuffer[0x1EC], 1);
memcpy(((PCHAR)&dwTime) + 1, &szBuffer[0x1ED], 1);
CloseHandle(hDisk);
if (dwTime != 0 )
{
return FALSE; //第 3 处
}
return TRUE;
}调用代码(示意)
[code]
DWORD sTime = 0;
for(int i = 0; i < 26; i++)
{
BOOL ret = GetUsbData('A'+ i, sTime);
if(ret) { .... }
else { .... }
}
[/code]哎,函数的参数很多,我给略了。
但除了第三处的判断那 有用外,前两处都是只与第一个参数有关。我的问题到不是说想知道为什么返回FALSE
因为,只要设置断点调试下,或者写 运行 Log,就知道last error 值了。不过,还不够,重要的是 为什么会在这个时候返回那个值呢?
所以,我想知道的就是标题里写的,如果一言难尽,可否指点一下哪里能解惑。
DWORD sTime = 0;
for(int i = 0; i < 26; i++)
{
if( 不是U盘) continue;
BOOL ret = GetUsbData('A'+ i, sTime);
ret = GetUsbData('A'+ i, sTime);//调用2+次后,貌似就运行正常了
ret = GetUsbData('A'+ i, sTime); if(ret) { .... }
else { .... }
}
根据 WM_DEVICECHANGE 的 DBT_DEVICEARRIVAL 类型消息,
1 通过SetupDixxx函数,得到 其 DriverKey Name,然后,
2 枚举所有Host Controller Driver 的 root hub的每一个端口,
3 获取,节点信息
4 获取其 Driver Key Name, 比较,符合了,就进行处理。我在运行中,发现有时获取到的信息是乱码,而且,U盘盘符加载很慢。(甚至很长时间都没反应)
通过调试,发现 在 3 与 4 步骤之间Sleep(1000);后,情况得到改善。但如果1000不够呢,我怎么动态改变?这种情况,是否属于资源抢用呢?不解中……
{
Sleep(1000)
}
我看过一个朗科的U盘, 厂商信息是俩汉字 (忘了)加一个'c' ……哦,我忘了说了,是获取USB设备信息中“包含乱码 ”或者“ 失败后我赋给一个_T("")值 ”不过问题,也不在这里,因为那是6楼所说的 步骤4之后的事情了,而且总结的情况是,3,4之间连续获取的话(DeviceControl + IOCTL控制码) 就会导致“U盘盘符弹出的慢”与“获取的是乱码”。