430 lines
13 KiB
C
430 lines
13 KiB
C
typedef struct _SCSI_PASS_THROUGH_WITH_BUFFERS
|
|
{
|
|
SCSI_PASS_THROUGH spt;
|
|
ULONG Filler; // realign buffers to double word boundary
|
|
UCHAR ucSenseBuf[32];
|
|
UCHAR ucDataBuf[512];
|
|
} SCSI_PASS_THROUGH_WITH_BUFFERS, *PSCSI_PASS_THROUGH_WITH_BUFFERS;
|
|
|
|
typedef struct _SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER
|
|
{
|
|
SCSI_PASS_THROUGH_DIRECT sptd;
|
|
ULONG Filler; // realign buffer to double word boundary
|
|
UCHAR ucSenseBuf[32];
|
|
} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, *PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER;
|
|
|
|
|
|
|
|
typedef struct _SCSI_TWOBYTES
|
|
{
|
|
UCHAR High;
|
|
UCHAR Low;
|
|
} SCSI_TWOBYTES, *PSCSI_TWOBYTES;
|
|
|
|
typedef struct _SCSI_THREEBYTES
|
|
{
|
|
UCHAR High;
|
|
UCHAR Mid;
|
|
UCHAR Low;
|
|
} SCSI_THREEBYTES, *PSCSI_THREEBYTES;
|
|
|
|
|
|
|
|
typedef struct _SCSI_MODE_HEADER
|
|
{
|
|
UCHAR ModeDataLength;
|
|
UCHAR MediumType;
|
|
UCHAR DeviceSpecificParameter;
|
|
UCHAR BlockDescriptorLength;
|
|
} SCSI_MODE_HEADER, *PSCSI_MODE_HEADER;
|
|
|
|
typedef struct _SCSI_MODE_FORMAT_PAGE
|
|
{
|
|
UCHAR PC_RES_PageCode;
|
|
UCHAR PageLength;
|
|
SCSI_TWOBYTES TracksPerZone;
|
|
SCSI_TWOBYTES AlternateSectorsPerZone;
|
|
SCSI_TWOBYTES AlternateTracksPerZone;
|
|
SCSI_TWOBYTES AlternateTracksPerLogicalUnit;
|
|
SCSI_TWOBYTES SectorsPerTrack;
|
|
SCSI_TWOBYTES DataBytesPerPhysicalSector;
|
|
SCSI_TWOBYTES Interleave;
|
|
SCSI_TWOBYTES TrackSkewFactor;
|
|
SCSI_TWOBYTES CylinderSkewFactor;
|
|
UCHAR FormattingBits;
|
|
SCSI_THREEBYTES Reserved;
|
|
} SCSI_MODE_FORMAT_PAGE, *PSCSI_MODE_FORMAT_PAGE;
|
|
|
|
//
|
|
// Define mode caching page.
|
|
//
|
|
|
|
typedef struct _MODE_CACHING_PAGE {
|
|
UCHAR PageCode : 6;
|
|
UCHAR Reserved : 1;
|
|
UCHAR PageSavable : 1;
|
|
UCHAR PageLength;
|
|
UCHAR ReadDisableCache : 1;
|
|
UCHAR MultiplicationFactor : 1;
|
|
UCHAR WriteCacheEnable : 1;
|
|
UCHAR Reserved2 : 5;
|
|
UCHAR WriteRetensionPriority : 4;
|
|
UCHAR ReadRetensionPriority : 4;
|
|
UCHAR DisablePrefetchTransfer[2];
|
|
UCHAR MinimumPrefetch[2];
|
|
UCHAR MaximumPrefetch[2];
|
|
UCHAR MaximumPrefetchCeiling[2];
|
|
}MODE_CACHING_PAGE, *PMODE_CACHING_PAGE;
|
|
|
|
|
|
//
|
|
// Command Descriptor Block constants.
|
|
//
|
|
|
|
#define CDB6GENERIC_LENGTH 6
|
|
#define CDB10GENERIC_LENGTH 10
|
|
|
|
#define SETBITON 1
|
|
#define SETBITOFF 0
|
|
//
|
|
// Mode Sense/Select page constants.
|
|
//
|
|
#define READ_DEFECT_PLIST 0x10
|
|
#define READ_DEFECT_GLIST 0x04
|
|
#define MODE_PAGE_ERROR_RECOVERY 0x01
|
|
#define MODE_PAGE_DISCONNECT 0x02
|
|
#define MODE_PAGE_FORMAT_DEVICE 0x03
|
|
#define MODE_PAGE_RIGID_GEOMETRY 0x04
|
|
#define MODE_PAGE_FLEXIBILE 0x05
|
|
#define MODE_PAGE_VERIFY_ERROR 0x07
|
|
#define MODE_PAGE_CACHING 0x08
|
|
#define MODE_PAGE_PERIPHERAL 0x09
|
|
#define MODE_PAGE_CONTROL 0x0A
|
|
#define MODE_PAGE_MEDIUM_TYPES 0x0B
|
|
#define MODE_PAGE_NOTCH_PARTITION 0x0C
|
|
#define MODE_SENSE_RETURN_ALL 0x3f
|
|
#define MODE_SENSE_CURRENT_VALUES 0x00
|
|
#define MODE_SENSE_CHANGEABLE_VALUES 0x40
|
|
#define MODE_SENSE_ALL_CHANGEABLE_VALUES 0x7F
|
|
#define MODE_SENSE_DEFAULT_VALUES 0x80
|
|
#define MODE_SENSE_SAVED_VALUES 0xc0
|
|
#define MODE_SENSE_FORMAT_DEVICE_PAGE 0x03
|
|
#define MODE_SENSE_DISABLE_BLOCK_DESCRIPTORS 0x08
|
|
#define MODE_SELECT_SAVE_PAGES 0x01
|
|
#define MODE_SELECT_DONT_SAVE_PAGES 0x00
|
|
#define MODE_PAGE_DEVICE_CONFIG 0x10
|
|
#define MODE_PAGE_MEDIUM_PARTITION 0x11
|
|
#define MODE_PAGE_DATA_COMPRESS 0x0f
|
|
|
|
//
|
|
// SCSI CDB operation codes
|
|
//
|
|
|
|
#define SCSIOP_TEST_UNIT_READY 0x00
|
|
#define SCSIOP_REZERO_UNIT 0x01
|
|
#define SCSIOP_REWIND 0x01
|
|
#define SCSIOP_REQUEST_BLOCK_ADDR 0x02
|
|
#define SCSIOP_REQUEST_SENSE 0x03
|
|
#define SCSIOP_FORMAT_UNIT 0x04
|
|
#define SCSIOP_READ_BLOCK_LIMITS 0x05
|
|
#define SCSIOP_REASSIGN_BLOCKS 0x07
|
|
#define SCSIOP_READ6 0x08
|
|
#define SCSIOP_RECEIVE 0x08
|
|
#define SCSIOP_WRITE6 0x0A
|
|
#define SCSIOP_PRINT 0x0A
|
|
#define SCSIOP_SEND 0x0A
|
|
#define SCSIOP_SEEK6 0x0B
|
|
#define SCSIOP_TRACK_SELECT 0x0B
|
|
#define SCSIOP_SLEW_PRINT 0x0B
|
|
#define SCSIOP_SEEK_BLOCK 0x0C
|
|
#define SCSIOP_PARTITION 0x0D
|
|
#define SCSIOP_READ_REVERSE 0x0F
|
|
#define SCSIOP_WRITE_FILEMARKS 0x10
|
|
#define SCSIOP_FLUSH_BUFFER 0x10
|
|
#define SCSIOP_SPACE 0x11
|
|
#define SCSIOP_INQUIRY 0x12
|
|
#define SCSIOP_VERIFY6 0x13
|
|
#define SCSIOP_RECOVER_BUF_DATA 0x14
|
|
#define SCSIOP_MODE_SELECT 0x15
|
|
#define SCSIOP_RESERVE_UNIT 0x16
|
|
#define SCSIOP_RELEASE_UNIT 0x17
|
|
#define SCSIOP_COPY 0x18
|
|
#define SCSIOP_ERASE 0x19
|
|
#define SCSIOP_MODE_SENSE 0x1A
|
|
#define SCSIOP_START_STOP_UNIT 0x1B
|
|
#define SCSIOP_STOP_PRINT 0x1B
|
|
#define SCSIOP_LOAD_UNLOAD 0x1B
|
|
#define SCSIOP_RECEIVE_DIAGNOSTIC 0x1C
|
|
#define SCSIOP_SEND_DIAGNOSTIC 0x1D
|
|
#define SCSIOP_MEDIUM_REMOVAL 0x1E
|
|
#define SCSIOP_READ_CAPACITY 0x25
|
|
#define SCSIOP_READ 0x28
|
|
#define SCSIOP_WRITE 0x2A
|
|
#define SCSIOP_SEEK 0x2B
|
|
#define SCSIOP_LOCATE 0x2B
|
|
#define SCSIOP_WRITE_VERIFY 0x2E
|
|
#define SCSIOP_VERIFY 0x2F
|
|
#define SCSIOP_SEARCH_DATA_HIGH 0x30
|
|
#define SCSIOP_SEARCH_DATA_EQUAL 0x31
|
|
#define SCSIOP_SEARCH_DATA_LOW 0x32
|
|
#define SCSIOP_SET_LIMITS 0x33
|
|
#define SCSIOP_READ_POSITION 0x34
|
|
#define SCSIOP_SYNCHRONIZE_CACHE 0x35
|
|
#define SCSIOP_READ_DEFECT_DATA 0x37
|
|
#define SCSIOP_COMPARE 0x39
|
|
#define SCSIOP_COPY_COMPARE 0x3A
|
|
#define SCSIOP_WRITE_DATA_BUFF 0x3B
|
|
#define SCSIOP_READ_DATA_BUFF 0x3C
|
|
#define SCSIOP_CHANGE_DEFINITION 0x40
|
|
#define SCSIOP_READ_SUB_CHANNEL 0x42
|
|
#define SCSIOP_READ_TOC 0x43
|
|
#define SCSIOP_READ_HEADER 0x44
|
|
#define SCSIOP_PLAY_AUDIO 0x45
|
|
#define SCSIOP_PLAY_AUDIO_MSF 0x47
|
|
#define SCSIOP_PLAY_TRACK_INDEX 0x48
|
|
#define SCSIOP_PLAY_TRACK_RELATIVE 0x49
|
|
#define SCSIOP_PAUSE_RESUME 0x4B
|
|
#define SCSIOP_LOG_SELECT 0x4C
|
|
#define SCSIOP_LOG_SENSE 0x4D
|
|
|
|
//
|
|
// Sense Data Format
|
|
//
|
|
|
|
typedef struct _SENSE_DATA {
|
|
UCHAR ErrorCode:7;
|
|
UCHAR Valid:1;
|
|
UCHAR SegmentNumber;
|
|
UCHAR SenseKey:4;
|
|
UCHAR Reserved:1;
|
|
UCHAR IncorrectLength:1;
|
|
UCHAR EndOfMedia:1;
|
|
UCHAR FileMark:1;
|
|
UCHAR Information[4];
|
|
UCHAR AdditionalSenseLength;
|
|
UCHAR CommandSpecificInformation[4];
|
|
UCHAR AdditionalSenseCode;
|
|
UCHAR AdditionalSenseCodeQualifier;
|
|
UCHAR FieldReplaceableUnitCode;
|
|
UCHAR SenseKeySpecific[3];
|
|
} SENSE_DATA, *PSENSE_DATA;
|
|
|
|
//
|
|
// Default request sense buffer size
|
|
//
|
|
|
|
#define SENSE_BUFFER_SIZE 18
|
|
|
|
//
|
|
// Sense codes
|
|
//
|
|
|
|
#define SCSI_SENSE_NO_SENSE 0x00
|
|
#define SCSI_SENSE_RECOVERED_ERROR 0x01
|
|
#define SCSI_SENSE_NOT_READY 0x02
|
|
#define SCSI_SENSE_MEDIUM_ERROR 0x03
|
|
#define SCSI_SENSE_HARDWARE_ERROR 0x04
|
|
#define SCSI_SENSE_ILLEGAL_REQUEST 0x05
|
|
#define SCSI_SENSE_UNIT_ATTENTION 0x06
|
|
#define SCSI_SENSE_DATA_PROTECT 0x07
|
|
#define SCSI_SENSE_BLANK_CHECK 0x08
|
|
#define SCSI_SENSE_UNIQUE 0x09
|
|
#define SCSI_SENSE_COPY_ABORTED 0x0A
|
|
#define SCSI_SENSE_ABORTED_COMMAND 0x0B
|
|
#define SCSI_SENSE_EQUAL 0x0C
|
|
#define SCSI_SENSE_VOL_OVERFLOW 0x0D
|
|
#define SCSI_SENSE_MISCOMPARE 0x0E
|
|
#define SCSI_SENSE_RESERVED 0x0F
|
|
|
|
//
|
|
// Additional tape bit
|
|
//
|
|
|
|
#define SCSI_ILLEGAL_LENGTH 0x20
|
|
#define SCSI_EOM 0x40
|
|
#define SCSI_FILE_MARK 0x80
|
|
|
|
//
|
|
// Additional Sense codes
|
|
//
|
|
|
|
#define SCSI_ADSENSE_NO_SENSE 0x00
|
|
#define SCSI_ADSENSE_LUN_NOT_READY 0x04
|
|
#define SCSI_ADSENSE_ILLEGAL_COMMAND 0x20
|
|
#define SCSI_ADSENSE_ILLEGAL_BLOCK 0x21
|
|
#define SCSI_ADSENSE_INVALID_LUN 0x25
|
|
#define SCSI_ADSENSE_INVALID_CDB 0x24
|
|
#define SCSI_ADSENSE_MUSIC_AREA 0xA0
|
|
#define SCSI_ADSENSE_DATA_AREA 0xA1
|
|
#define SCSI_ADSENSE_VOLUME_OVERFLOW 0xA7
|
|
|
|
#define SCSI_ADSENSE_NO_MEDIA_IN_DEVICE 0x3a
|
|
#define SCSI_ADWRITE_PROTECT 0x27
|
|
#define SCSI_ADSENSE_MEDIUM_CHANGED 0x28
|
|
#define SCSI_ADSENSE_BUS_RESET 0x29
|
|
#define SCSI_ADSENSE_TRACK_ERROR 0x14
|
|
#define SCSI_ADSENSE_SEEK_ERROR 0x15
|
|
#define SCSI_ADSENSE_REC_DATA_NOECC 0x17
|
|
#define SCSI_ADSENSE_REC_DATA_ECC 0x18
|
|
|
|
//
|
|
// Additional sense code qualifier
|
|
//
|
|
|
|
#define SCSI_SENSEQ_FORMAT_IN_PROGRESS 0x04
|
|
#define SCSI_SENSEQ_INIT_COMMAND_REQUIRED 0x02
|
|
#define SCSI_SENSEQ_MANUAL_INTERVENTION_REQUIRED 0x03
|
|
#define SCSI_SENSEQ_BECOMING_READY 0x01
|
|
#define SCSI_SENSEQ_FILEMARK_DETECTED 0x01
|
|
#define SCSI_SENSEQ_SETMARK_DETECTED 0x03
|
|
#define SCSI_SENSEQ_END_OF_MEDIA_DETECTED 0x02
|
|
#define SCSI_SENSEQ_BEGINNING_OF_MEDIA_DETECTED 0x04
|
|
|
|
//
|
|
// Define mode flexible disk page.
|
|
//
|
|
|
|
typedef struct _MODE_FLEXIBLE_DISK_PAGE {
|
|
UCHAR PageCode : 6;
|
|
UCHAR Reserved : 1;
|
|
UCHAR PageSavable : 1;
|
|
UCHAR PageLength;
|
|
UCHAR TransferRate[2];
|
|
UCHAR NumberOfHeads;
|
|
UCHAR SectorsPerTrack;
|
|
UCHAR BytesPerSector[2];
|
|
UCHAR NumberOfCylinders[2];
|
|
UCHAR StartWritePrecom[2];
|
|
UCHAR StartReducedCurrent[2];
|
|
UCHAR StepRate[2];
|
|
UCHAR StepPluseWidth;
|
|
UCHAR HeadSettleDelay[2];
|
|
UCHAR MotorOnDelay;
|
|
UCHAR MotorOffDelay;
|
|
UCHAR Reserved2 : 5;
|
|
UCHAR MotorOnAsserted : 1;
|
|
UCHAR StartSectorNumber : 1;
|
|
UCHAR TrueReadySignal : 1;
|
|
UCHAR StepPlusePerCyclynder : 4;
|
|
UCHAR Reserved3 : 4;
|
|
UCHAR WriteCompenstation;
|
|
UCHAR HeadLoadDelay;
|
|
UCHAR HeadUnloadDelay;
|
|
UCHAR Pin2Usage : 4;
|
|
UCHAR Pin34Usage : 4;
|
|
UCHAR Pin1Usage : 4;
|
|
UCHAR Pin4Usage : 4;
|
|
UCHAR MediumRotationRate[2];
|
|
UCHAR Reserved4[2];
|
|
}MODE_FLEXIBLE_DISK_PAGE, *PMODE_FLEXIBLE_DISK_PAGE;
|
|
|
|
//
|
|
// Define mode format page.
|
|
//
|
|
|
|
typedef struct _MODE_FORMAT_PAGE {
|
|
UCHAR PageCode : 6;
|
|
UCHAR Reserved : 1;
|
|
UCHAR PageSavable : 1;
|
|
UCHAR PageLength;
|
|
UCHAR TracksPerZone[2];
|
|
UCHAR AlternateSectorsPerZone[2];
|
|
UCHAR AlternateTracksPerZone[2];
|
|
UCHAR AlternateTracksPerLogicalUnit[2];
|
|
UCHAR SectorsPerTrack[2];
|
|
UCHAR BytesPerPhysicalSector[2];
|
|
UCHAR Interleave[2];
|
|
UCHAR TrackSkewFactor[2];
|
|
UCHAR CylinderSkewFactor[2];
|
|
UCHAR Reserved2 : 4;
|
|
UCHAR SurfaceFirst : 1;
|
|
UCHAR RemovableMedia : 1;
|
|
UCHAR HardSectorFormating : 1;
|
|
UCHAR SoftSectorFormating : 1;
|
|
UCHAR Reserved3[2];
|
|
} MODE_FORMAT_PAGE, *PMODE_FORMAT_PAGE;
|
|
|
|
//
|
|
// Define rigid disk driver geometry page.
|
|
//
|
|
|
|
typedef struct _MODE_RIGID_GEOMETRY_PAGE {
|
|
UCHAR PageCode : 6;
|
|
UCHAR Reserved : 1;
|
|
UCHAR PageSavable : 1;
|
|
UCHAR PageLength;
|
|
UCHAR NumberOfCylinders[2];
|
|
UCHAR NumberOfHeads;
|
|
UCHAR StartWritePrecom[2];
|
|
UCHAR StartReducedCurrent[2];
|
|
UCHAR DriveStepRate[2];
|
|
UCHAR LandZoneCyclinder[2];
|
|
UCHAR RotationalPositionLock : 2;
|
|
UCHAR Reserved2 : 6;
|
|
UCHAR RotationOffset;
|
|
UCHAR Reserved3;
|
|
UCHAR RoataionRate[2];
|
|
UCHAR Reserved4[2];
|
|
}MODE_RIGID_GEOMETRY_PAGE, *PMODE_RIGID_GEOMETRY_PAGE;
|
|
|
|
//
|
|
// Define read write recovery page
|
|
//
|
|
|
|
typedef struct _MODE_READ_WRITE_RECOVERY_PAGE {
|
|
|
|
UCHAR PageCode : 6;
|
|
UCHAR Reserved1 : 1;
|
|
UCHAR PSBit : 1;
|
|
UCHAR PageLength;
|
|
UCHAR DCRBit : 1;
|
|
UCHAR DTEBit : 1;
|
|
UCHAR PERBit : 1;
|
|
UCHAR EERBit : 1;
|
|
UCHAR RCBit : 1;
|
|
UCHAR TBBit : 1;
|
|
UCHAR ARRE : 1;
|
|
UCHAR AWRE : 1;
|
|
UCHAR ReadRetryCount;
|
|
UCHAR Reserved4[4];
|
|
UCHAR WriteRetryCount;
|
|
UCHAR Reserved5[3];
|
|
|
|
} MODE_READ_WRITE_RECOVERY_PAGE, *PMODE_READ_WRITE_RECOVERY_PAGE;
|
|
|
|
/* Prototypes */
|
|
|
|
VOID DoInquiry(PSCSI_PASS_THROUGH_WITH_BUFFERS, HANDLE);
|
|
|
|
VOID DoModeSense(PSCSI_PASS_THROUGH_WITH_BUFFERS, HANDLE, ULONG);
|
|
|
|
VOID DoModeSelect(PSCSI_PASS_THROUGH_WITH_BUFFERS, HANDLE, ULONG, ULONG);
|
|
|
|
VOID
|
|
PrintError(ULONG);
|
|
|
|
VOID
|
|
PrintDataBuffer(PUCHAR, ULONG);
|
|
|
|
VOID
|
|
PrintInquiryDataBuffer(PUCHAR, ULONG);
|
|
|
|
VOID
|
|
PrintInquiryData(PVOID);
|
|
|
|
VOID
|
|
PrintInquiryStatusResults(BOOLEAN, DWORD, PSCSI_PASS_THROUGH_WITH_BUFFERS, ULONG);
|
|
|
|
VOID
|
|
PrintSenseInfo(PSCSI_PASS_THROUGH_WITH_BUFFERS);
|
|
|
|
BOOL
|
|
SetDiscPage(PUCHAR, PUCHAR, ULONG);
|
|
|
|
BOOL
|
|
EnableWriteCache(PUCHAR, ULONG, PUCHAR, ULONG);
|
|
|
|
BOOL
|
|
VerifyModePage( PUCHAR, PUCHAR, ULONG);
|
|
|