Strange problem with read-only virtual disk

Dear storage stack experts,

I created an SCSI miniport driver which emulates a virtual disk that
maps to an image file containing a FAT file system. By reading many
postings on this list I learned about all the ugly hacks required to
make this work. So my current implementation works quite well on XP, as
long as I allow read and write access to the disk. But, if my image file
resides on a CDROM then I emulate a read-only disk.

The read-only disk behaves as follows:
When I try to copy a file to it then I get the error message “Unable to
write, please remove write protection” which is fine.
When I read a file from the disk then, after a second or so, XP shows an
error message (yellow bubble) that says “Delayed Write Failed. Windows
was unable to save all the data for the file…”. This maps to
STATUS_LOST_WRITEBEHIND_DATA.

Any idea why this happens?
I do not understand why FAT FSD tries to write to the media. I suppose
this happens to update last access timestamps. But it makes no sense to
try that on a read-only disk.

More info:
I emulate a read-only disk in the following way:

  • on INQUIRY return DeviceType=DIRECT_ACCESS_DEVICE and RemovableMedia=1
  • on MODE SENSE 6 and 10 return
    DeviceSpecificParameter=MODE_DSP_WRITE_PROTECT
  • on WRITE fail the SRB with SenseKey=SCSI_SENSE_DATA_PROTECT,
    ASC=SCSI_ADSENSE_WRITE_PROTECT

I verified that the port driver responds to the following IOCTLs:

  • IOCTL_DISK_IS_WRITABLE returns STATUS_MEDIA_WRITE_PROTECTED
  • IOCTL_STORAGE_GET_MEDIA_TYPES_EX returns (MEDIA_CURRENTLY_MOUNTED |
    MEDIA_READ_WRITE | MEDIA_WRITE_PROTECTED) in
    DEVICE_MEDIA_INFO.DeviceSpecific.DiskInfo.MediaCharacteristics

Thanks for your help.

Udo

> When I read a file from the disk then, after a second or so,…

“Delayed Write Failed. Windows was unable to save all the data for the
file…”. This maps to STATUS_LOST_WRITEBEHIND_DATA.

This means that the physical page frames are marked as dirty and Mapped Page
Writer thread tries to write them on a disk.
I suspect that you use MmProbeAndLockPages with the IoWrirteAccess, the side
effect of this call is that when the MmUnlockPages function is called the
page frames are marked as dirty.


Slava Imameyev, xxxxx@hotmail.com

“Udo Eberhardt” wrote in message
news:xxxxx@ntdev…
> Dear storage stack experts,
>
> I created an SCSI miniport driver which emulates a virtual disk that maps
> to an image file containing a FAT file system. By reading many postings on
> this list I learned about all the ugly hacks required to make this work.
> So my current implementation works quite well on XP, as long as I allow
> read and write access to the disk. But, if my image file resides on a
> CDROM then I emulate a read-only disk.
>
> The read-only disk behaves as follows:
> When I try to copy a file to it then I get the error message “Unable to
> write, please remove write protection” which is fine.
> When I read a file from the disk then, after a second or so, XP shows an
> error message (yellow bubble) that says “Delayed Write Failed. Windows was
> unable to save all the data for the file…”. This maps to
> STATUS_LOST_WRITEBEHIND_DATA.
>
> Any idea why this happens?
> I do not understand why FAT FSD tries to write to the media. I suppose
> this happens to update last access timestamps. But it makes no sense to
> try that on a read-only disk.
>
> More info:
> I emulate a read-only disk in the following way:
> - on INQUIRY return DeviceType=DIRECT_ACCESS_DEVICE and RemovableMedia=1
> - on MODE SENSE 6 and 10 return
> DeviceSpecificParameter=MODE_DSP_WRITE_PROTECT
> - on WRITE fail the SRB with SenseKey=SCSI_SENSE_DATA_PROTECT,
> ASC=SCSI_ADSENSE_WRITE_PROTECT
>
> I verified that the port driver responds to the following IOCTLs:
> - IOCTL_DISK_IS_WRITABLE returns STATUS_MEDIA_WRITE_PROTECTED
> - IOCTL_STORAGE_GET_MEDIA_TYPES_EX returns (MEDIA_CURRENTLY_MOUNTED |
> MEDIA_READ_WRITE | MEDIA_WRITE_PROTECTED) in
> DEVICE_MEDIA_INFO.DeviceSpecific.DiskInfo.MediaCharacteristics
>
>
> Thanks for your help.
>
> Udo
>

Thank you very much for this great tip! This was key to success!

However, because I have an scsi miniport driver which does not give me
access to IRPs and MDLs the situation is a little bit different. The
solution is to create an intermediate buffer, to ZwReadFile the data
into it and then to memcpy to the SRB. This avoids IoWrirteAccess
locking of the buffer within ZwReadFile.

Thanks again.

Udo

Slava Imameyev wrote:

> When I read a file from the disk then, after a second or so,…
> “Delayed Write Failed. Windows was unable to save all the data for the
> file…”. This maps to STATUS_LOST_WRITEBEHIND_DATA.

This means that the physical page frames are marked as dirty and Mapped Page
Writer thread tries to write them on a disk.
I suspect that you use MmProbeAndLockPages with the IoWrirteAccess, the side
effect of this call is that when the MmUnlockPages function is called the
page frames are marked as dirty.