文件创建失败。第二次成功

时间:2018-05-09 12:21:23

标签: delphi delphi-2010

首先对不起 - 对于这个问题,由于涉及一些专门的硬件,因此完全不可能创建一个最小的例子。

所以......我们已经建立了一个通过USB连接到PC的录音设备,并模拟了SD卡(显示为驱动器)。该驱动器最初是只读的 但是可以通过写入特殊扇区(MBR和FAT之间)来切换到读/写操作,这样就可以在该驱动器上创建文件。

到目前为止一切顺利。现在,当创建一个文件抱怨媒体是只读时,Windows似乎会创建一些hickup。第二次尝试创建文件实际上是成功的。

以下是执行的代码:

 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提出驱动器实际上没有写保护? 我尝试了一些IO控制代码: IOCTLCheckVerify IOCTLUpdateProperties

但没有成功。

我不期待任何代码,但有些想法会被高度关注。

稍作澄清: fMK5UsbComm拥有2个句柄:一个用于卷,一个用于与卷关联的物理设备。首先打开物理设备句柄,进行特殊的读取操作,取消设备中的只读标志,然后重新打开句柄读/写(允许与设备进行特殊通信)。

1 个答案:

答案 0 :(得分:0)

好吧我觉得我现在得到了 - 所以这只适用于任何最终陷入同一陷阱的人:

  1. 通过发出SYNCHRONIZED访问标志而不是GENERIC_READ或GENERIC_WRITE获得驱动器句柄。这加速了设备的检测,因为它当时没有完全安装(例如,读取设备上的FAT很慢),但可以进行较低级别的呼叫。
  2. 我需要关闭驱动器句柄,使用GENERIC_READ或GENERIC_WRITE重新打开它,发出FSCTL_DISMOUNT_VOLUME命令,然后再次重新打开驱动器句柄,安装驱动器并让Windows更新内部卷信息。