USB模拟SD卡设备首次创建文件失败、二次成功的原因及解决咨询
先跟大伙道个歉——因为涉及专用硬件,没法做最小复现示例。
我们团队开发了一款USB录制设备,它会模拟成SD卡(在Windows里显示为一个驱动器)。这个驱动器默认是只读状态,但可以通过写入MBR和FAT之间的特殊扇区切换成读写模式,之后就能在上面创建文件了。
遇到的诡异问题
现在碰到个搞不懂的情况:第一次尝试在这个驱动器上创建文件时,Windows会报错提示介质只读,但第二次再试就完全正常了。
我目前用的代码逻辑是这样的:
if not (fMK5UsbComm as TMK5USBComm).IsWritable then raise Exception.Create('WTF'); try fs:=TFileStream.Create(fMK5UsbComm.DriveLetter + ':\Tom24.ini', fmCreate or fmOpenReadWrite); try fs.WriteBuffer(ss[1], length(ss)); finally fs.Free; end; except fs:=TFileStream.Create(fMK5UsbComm.DriveLetter + ':\Tom24.ini', fmCreate or fmOpenReadWrite); try fs.WriteBuffer(ss[1], length(ss)); finally fs.Free; end; end;
其中判断是否可写的IsWritable方法实现是:
function TVolume.IsWritable: boolean; var numBytesReturned : DWORD; begin numBytesReturned := 0; Result := DeviceIoControl( fHandle, IOCTLDiskIsWritable, nil, 0, nil, 0, numBytesReturned, nil); if not Result then begin if GetLastError <> ERROR_WRITE_PROTECT then RaiseLastOSError; end; end;
想请教的两个核心问题
- 为什么第一次创建文件流会失败,第二次却能成功?
- 有没有办法让Windows立刻识别到驱动器已经解除只读状态?我试过
IOCTLCheckVerify、IOCTLUpdateProperties这些IO控制指令,但都没起作用。
不需要给具体代码,只要相关的思路建议就好。
补充说明一下:fMK5UsbComm里持有两个句柄,一个对应卷,一个对应关联的物理设备。物理设备句柄最初是只读模式打开的,执行特殊读取操作取消设备的只读标记后,会重新以读写模式打开(这样才能和设备进行特殊通信)。
内容的提问来源于stack exchange,提问作者mrabat
相关产品推荐
相关产品推荐

