Alter.Org.UA  
 << Back Home RU ru   Donate Donate www/www1/www2

NT SCSI Pass Through Interface (SPTI) behavior

SPTI is a perfect technology for direct communication with SCSI-compatible devices for Windows NT family. SPTI unifies communication interface for the following device classes (the list can appear much more wide):

  • SCSI devices, connected via SCSI-controller
  • devices using SCSI command set, connected via non-SCSI-controllers
    • all currently available IDE/ATAPI CD/DVD-drives and most of very old ones.
    • LPT, USB and FireWire HDD and CD/DVD-drives.
  • devices with driver-side SCSI-interface emulation - IDE/ATA HDD

You can pass any SCSI command with any paramenters through SPTI. You can also obtain complete error condition information (SenseInfo) from device. Look at the brief list of advantages:

  • Works under all NT-family OS'es.
  • Doesn't require any additional drivers installed. (Such as multiple implementaions of ASPI with their multiple bugs).
  • Is available in Win32 via DeviceIoControl() with handle to physical device (see. MSDN, CreateFileEx(), \\.\<DriveLetter>:, etc.)

SPTI is pretty, but there are some undocumented troubles, those I have meet. The further story is about them.

You can read much more about SCSI commands for CD/DVD drives in MMC specs.

Transfer length limitations

Problem: IOCTL_SCSI_PASS_THROUGH_DIRECT fails when I attempt to transfer 64k from Win32 using DeviceIoControl(). Port driver returns STATUS_INVALID_PARAMETER. MS DDK Help states, that such error occures if data buffer has improper size. Knowledge base (PSS ID Number: Q126369) states, that we must use IOCTL_SCSI_GET_CAPABILITIES to obtain MaximumTransferLength and MaximumPhysicalPages. According to docs user buffer is copied to temporary system-allocated buffer (METHOD_BUFFERED) and after operation completion data from temporary buffer is copied back to user buffer.

I checked it. MaximumTransferLength is 64k, no problem should be. MaximumPhysicalPages is 16, also no problem. So why it doesn't work ?

Answer: user buffer is passed down as is. Port driver compares its size with MaximumTransferLength. That is ok. Then it calculates how much pages spans user buffer. Because Win32 allocates 8-byte aligned memory blocks, 64k buffer will usually span 17 pages. That was the reason for my problem.

Solution: trivial. Buffer must be PAGE_SIZE-aligned. In kernel mode memory blocks greater than PAGE_SIZE are aligned to PAGE_SIZE by memory manager. In user mode you should either allocate larger buffer and use PAGE_SIZE-aligned part of it or implement own heap manager specially for large blocks.

Auto-sense (device error reporting) issues

Small trouble: when SenseInfoOffset is used you should not set SenseInfoLength greater than sizeof(SENSE_DATA) - 24 bytes. If you specify extra length, no Sense Info will be returned. This happens because when error occures Port-driver sends REQUEST_SENSE commend to device. It uses user-specified SenseInfoLength for this request. The device cannot return more than 24 bytes, and an error is generated.

VMWare compatibility

Trouble: Imagine physical ATAPI CD-Recorder which is mapped to IDE bus of virtual machine. Neither CD-recording software using SPTI can operate properly. I discovered, that VMWare blocks MODE_SELECT command with MODE_PAGE_WRITE_PARAMS - 0x05 and WRITE commands. Further investigations shown that the trouble affected all ways of sending write requests.

Solution: tune VMWare in order to expose physical ATAPI CD-recorder as SCSI device inside virtual machine.

<< Back designed by Alter aka Alexander A. Telyatnikov powered by Apache+PHP under FBSD © 2002-2014