http://stackoverflow.com/questions/14363152/send-custom-commands-to-mass-storage-device
I have developed a mass-storage device, and I'd a like a PC application to send/receive some custom commands to it. Normally one would create a composite USB device for this (MSC+HID) and send the commands over HID. But is it possible to do this with only the mass-storage class? Some things I thought of:
- Send the data in unused SCSI commands (Vista requires administrator rights for this)
- Write the data to a "magic" sector, and parse it on the device as soon as it notices that specific sector being written too (Some windows version dont allow raw disk access)
- Send the data by placing them in a .txt file on the disk (very complicated, because the device needs to parse the FAT tables to read the file, and has no way of being notified when the .txt file is updated)
Can someone think of any other hacks, that would work for this purpose? Or is the only option to create a HID device?
The MSC you mentioned is also "USB" Mass Storage Device ?
If yes then you can use SCSI_PATH_THROUGH to communicate with this USB MSC !
Ex. issuing Write command to USB MSC can be achieved by below code snippet:
BOOL LogicalWriteCmd( HANDLE fileHandle, ULONG LBA, ULONG SectorCnt, PVOID DataBuffer ) { SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptdwb; ULONG returned, length; BOOL status; ZeroMemory( &sptdwb, sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER) ); length = SectorCnt << SECTOR_SIZE_SHIFT_BIT; sptdwb.sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT); sptdwb.sptd.PathId = 0; sptdwb.sptd.TargetId = 0; sptdwb.sptd.Lun = 0; sptdwb.sptd.CdbLength = CDB10GENERIC_LENGTH; sptdwb.sptd.DataIn = SCSI_IOCTL_DATA_OUT; sptdwb.sptd.SenseInfoLength = SPT_SENSE_LENGTH; sptdwb.sptd.DataTransferLength = length; sptdwb.sptd.TimeOutValue = g_ulTimeOut; sptdwb.sptd.DataBuffer = DataBuffer; sptdwb.sptd.SenseInfoOffset = offsetof( SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf ); sptdwb.sptd.Cdb[ 0 ] = SCSIOP_WRITE; sptdwb.sptd.Cdb[ 2 ] = ( UCHAR )( LBA >> 24 ); sptdwb.sptd.Cdb[ 3 ] = ( UCHAR )( LBA >> 16 ); sptdwb.sptd.Cdb[ 4 ] = ( UCHAR )( LBA >> 8 ); sptdwb.sptd.Cdb[ 5 ] = ( UCHAR )( LBA ); sptdwb.sptd.Cdb[ 7 ] = SectorCnt >> 8; sptdwb.sptd.Cdb[ 8 ] = (UCHAR) SectorCnt; length = sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER); status = DeviceIoControl( fileHandle, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptdwb, length, &sptdwb, length, &returned, FALSE ); if ( ( sptdwb.sptd.ScsiStatus == 0 ) && ( status != 0 ) ) { return TRUE; } return FALSE; }
And you can create your own vendor/custom commands then send it to USB MSC by above way. But your device should identify them correctly !
I agree that this would be the best way to do it, but my main problem is KB241374: "Note that only members of the administrator's group have the correct authority to send SCSI pass through requests." So my application will always need to be launched as an Administrator-user.
yes ! It sure is...Before I used to use ASPI to access USB MSD
(please check en.wikipedia.org/wiki/Advanced_SCSI_Programming_Interface )
Advanced SCSI Programming Interface
In computing, ASPI (Advanced SCSI Programming Interface) is an Adaptec-developed programming interface which standardizes communication on a computer bus between a SCSI driver module on the one hand and SCSI (and ATAPI) peripherals on the other.
The ASPI manager software provides an interface between ASPI modules (device drivers or applications with direct SCSI support), a SCSI host adapter, and SCSI devices connected to the host adapter. The ASPI manager is specific to the host adapter and operating system; its primary role is to abstract the host adapter specifics and provide a generic software interface to SCSI devices.
On Windows 9x and Windows NT, the ASPI manager is generic and relies on the services of SCSI miniport drivers. On those systems, the ASPI interface is designed for applications which require SCSI pass-through functionality (such as CD-ROM burning software).
The primary operations supported by ASPI are discovery of host adapters and attached devices, and submitting SCSI commands to devices via SRBs (SCSI Request Blocks). ASPI supports concurrent execution of SCSI commands.
ASPI was developed by Adaptec around 1990. It was initially designed to support DOS, OS/2, Windows 3.x, and Novell NetWare. It was originally written to support SCSI devices; support for ATAPI devices was added later. Most other SCSI host adapter vendors (for example BusLogic, DPT, AMI, Future Domain, DTC) shipped their own ASPI managers with their hardware.[2]
Adaptec also developed generic SCSI disk and CD-ROM drivers for DOS (ASPICD.SYS and ASPIDISK.SYS).
Microsoft licensed the interface for use with Windows 9x series. At the same time Microsoft developed SCSI Pass Through Interface (SPTI), an in-house substitute that worked on the NT platform. Microsoft did not include ASPI in Windows 2000/XP, in favor of its own SPTI. Users may still download ASPI from Adaptec. A number of CD/DVD applications also continue to offer their own implementations of ASPI layer.
ASPI was provided by the following drivers.
Operating System | Driver Filename | Bundled |
---|---|---|
DOS | ASPI4DOS.SYS | No |
Windows 3.1x | WINASPI.DLL | No |
Windows 95, 98 and ME | WNASPI32.DLL, WINASPI.DLL, APIX.VXD and ASPIENUM.VXD | Yes |
Windows NT, 2000, XP | WNASPI32.DLL, ASPI32.SYS | No |
FreeDOS | USBASPI.SYS | Unknown |
- SCSI Pass-Through Direct (SPTD)
- SCSI Pass Through Interface (SPTI)
SCSI Pass-Through Direct
SCSI Pass Through Direct (SPTD) is a proprietarydevice driver and application programming interface (API) developed by Duplex Secure Ltd. that provides a new method of access to SCSIstorage devices. The SPTD API is not open to the public.
SPTD is used by Daemon Tools and Alcohol 120%. It is also utilized in PowerArchiver Pro 2010 (v11.60+); however, a configurable option is available to disable it.[1] It is known to be incompatible with kernel-mode debugging includingWinDbg and Microsoft's other command line debuggers as well as SoftICE. Further, certain versions of the freeware optical media burning software ImgBurn will issue a warning, "SPTD can have a detrimental effect on drive performance", if the application detects that SPTD is active or installed.
ConeXware, Inc. (the maker of PowerArchiver) claims that in their internal testing, SPTD improved optical drive performance by up to 20 percent in comparison to the "old school" SCSI Pass Through Interface
SCSI Pass Through Interface
SCSI Pass Through Interface (SPTI) is an application programming interface (API) accessing a SCSI device. It is developed by Microsoft Corporation and is part of the Windows NT family of operating systems.
The storage port drivers provide an interface for Win32 applications to send SCSI Command Descriptor Block (CDB) messages to SCSI devices. The interfaces are IOCTL_SCSI_PASS_THROUGH and IOCTL_SCSI_PASS_THROUGH_DIRECT. Applications can build a pass-through request and send it to the device by using this IOCTL.
SPTI is accessible to Windows software using the DeviceIoControl Windows API.
ImgBurn offers SPTI as a method for accessing optical disc drives.
SCSI
Small Computer System Interface (SCSI, /ˈskʌzi/ skuz-ee) is a set of standards for physically connecting and transferring data between computers and peripheral devices. The SCSI standards define commands, protocols and electrical and opticalinterfaces. SCSI is most commonly used for hard disks and tape drives, but it can connect a wide range of other devices, including scanners and CD drives, although not all controllers can handle all devices. The SCSI standard defines command sets for specific peripheral device types; the presence of "unknown" as one of these types means that in theory it can be used as an interface to almost any device, but the standard is highly pragmatic and addressed toward commercial requirements.
SCSI is an intelligent, peripheral, buffered, peer to peer interface. It hides the complexity of physical format. Every device attaches to the SCSI bus in a similar manner. Up to 8 or 16 devices can be attached to a single bus. There can be any number of hosts and peripheral devices but there should be at least one host. SCSI uses handshake signals between devices, SCSI-1, SCSI-2 have the option of parity error checking. Starting with SCSI-U160 (part of SCSI-3) all commands and data are error checked by a CRC32 checksum. The SCSI protocol defines communication from host to host, host to a peripheral device, peripheral device to a peripheral device. However most peripheral devices are exclusively SCSI targets, incapable of acting as SCSI initiators—unable to initiate SCSI transactions themselves. Therefore peripheral-to-peripheral communications are uncommon, but possible in most SCSI applications. The Symbios Logic 53C810 chip is an example of a PCI host interface that can act as a SCSI target.
SCSI command protocol
In addition to many different hardware implementations, the SCSI standards also include an extensive set of command definitions. The SCSI command architecture was originally defined forparallel SCSI buses but has been carried forward with minimal change for use with iSCSI and serial SCSI. Other technologies which use the SCSI command set include the ATA Packet Interface, USB Mass Storage class and FireWire SBP-2.
In SCSI terminology, communication takes place between an initiator and a target. The initiator sends a command to the target, which then responds. SCSI commands are sent in a Command Descriptor Block (CDB). The CDB consists of a one byte operation code followed by five or more bytes containing command-specific parameters.
At the end of the command sequence, the target returns a status code byte, such as 00h for success, 02h for an error (called a Check Condition), or 08h for busy. When the target returns a Check Condition in response to a command, the initiator usually then issues a SCSI Request Sense command in order to obtain a key code qualifier (KCQ) from the target. The Check Condition and Request Sense sequence involves a special SCSI protocol called a Contingent Allegiance Condition.
There are 4 categories of SCSI commands: N (non-data), W (writing data from initiator to target), R (reading data), and B (bidirectional). There are about 60 different SCSI commandsin total, with the most commonly used being:
- Test unit ready: Queries device to see if it is ready for data transfers (disk spun up, media loaded, etc.).
- Inquiry: Returns basic device information.
- Request sense: Returns any error codes from the previous command that returned an error status.
- Send diagnostic and Receive diagnostic results: runs a simple self-test, or a specialised test defined in a diagnostic page.
- Start/Stop unit: Spins disks up and down, or loads/unloads media (CD, tape, etc.).
- Read capacity: Returns storage capacity.
- Format unit: Prepares a storage medium for use. In a disk, a low level format will occur. Some tape drives will erase the tape in response to this command.
- Read (four variants): Reads data from a device.
- Write (four variants): Writes data to a device.
- Log sense: Returns current information from log pages.
- Mode sense: Returns current device parameters from mode pages.
- Mode select: Sets device parameters in a mode page.
Each device on the SCSI bus is assigned a unique SCSI identification number or ID. Devices may encompass multiple logical units, which are addressed by logical unit number (LUN). Simple devices have just one LUN, more complex devices may have multiple LUNs.
A "direct access" (i.e. disk type) storage device consists of a number of logical blocks, addressed by Logical Block Address (LBA). A typical LBA equates to 512 bytes of storage. The usage of LBAs has evolved over time and so four different command variants are provided for reading and writing data. The Read(6) and Write(6) commands contain a 21-bit LBA address. TheRead(10), Read(12), Read Long, Write(10), Write(12), and Write Long commands all contain a 32-bit LBA address plus various other parameter options.
The capacity of a "sequential access" (i.e. tape-type) device is not specified because it depends, amongst other things, on the length of the tape, which is not identified in a machine-readable way. Read and write operations on a sequential access device begin at the current tape position, not at a specific LBA. The block size on sequential access devices can either be fixed or variable, depending on the specific device. Tape devices such as half-inch9-track tape, DDS (4 mm tapes physically similar to DAT), Exabyte, etc., support variable block sizes.