Get CD audio track frame?
BTW: Setting srbExec\CDBByte[1] to $02 retrieves the TOC in MSF-Format
(minutes (addr[1]), seconds (addr[2]) and frames (addr[3]))
This may also be quite handy...
(minutes (addr[1]), seconds (addr[2]) and frames (addr[3]))
This may also be quite handy...
Code: Select all
;***************************************************************************
;
; Name: SCSIDEFS.H
;
; Description: SCSI definitions ('PureBasic' Language)
;
;***************************************************************************
;***************************************************************************
; %%% TARGET STATUS VALUES %%%
;***************************************************************************
#STATUS_GOOD = $00 ; Status Good
#STATUS_CHKCOND = $02 ; Check Condition
#STATUS_CONDMET = $04 ; Condition Met
#STATUS_BUSY = $08 ; Busy
#STATUS_INTERM = $10 ; Intermediate
#STATUS_INTCDMET = $14 ; Intermediate-condition met
#STATUS_RESCONF = $18 ; Reservation conflict
#STATUS_COMTERM = $22 ; Command Terminated
#STATUS_QFULL = $28 ; Queue full
;***************************************************************************
; %%% SCSI MISCELLANEOUS EQUATES %%%
;***************************************************************************
#MAXLUN = 7 ; Maximum Logical Unit Id
#MAXTARG = 7 ; Maximum Target Id
#MAX_SCSI_LUNS = 64 ; Maximum Number of SCSI LUNs
#MAX_NUM_HA = 8 ; Maximum Number of SCSI HA's
;\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
;
; %%% SCSI COMMAND OPCODES %%%
;
;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
;***************************************************************************
; %%% Commands for all Device Types %%%
;***************************************************************************
#SCSI_CHANGE_DEF = $40 ; Change Definition (Optional)
#SCSI_COMPARE = $39 ; Compare (O)
#SCSI_COPY = $18 ; Copy (O)
#SCSI_COP_VERIFY = $3A ; Copy and Verify (O)
#SCSI_INQUIRY = $12 ; Inquiry (MANDATORY)
#SCSI_LOG_SELECT = $4C ; Log Select (O)
#SCSI_LOG_SENSE = $4D ; Log Sense (O)
#SCSI_MODE_SEL6 = $15 ; Mode Select 6-byte (Device Specific)
#SCSI_MODE_SEL10 = $55 ; Mode Select 10-byte (Device Specific)
#SCSI_MODE_SEN6 = $1A ; Mode Sense 6-byte (Device Specific)
#SCSI_MODE_SEN10 = $5A ; Mode Sense 10-byte (Device Specific)
#SCSI_READ_BUFF = $3C ; Read Buffer (O)
#SCSI_REQ_SENSE = $03 ; Request Sense (MANDATORY)
#SCSI_SEND_DIAG = $1D ; Send Diagnostic (O)
#SCSI_TST_U_RDY = $00 ; Test Unit Ready (MANDATORY)
#SCSI_WRITE_BUFF = $3B ; Write Buffer (O)
;***************************************************************************
; %%% Commands Unique to Direct Access Devices %%%
;***************************************************************************
#SCSI_COMPARE = $39 ; Compare (O)
#SCSI_FORMAT = $04 ; Format Unit (MANDATORY)
#SCSI_LCK_UN_CAC = $36 ; Lock Unlock Cache (O)
#SCSI_PREFETCH = $34 ; Prefetch (O)
#SCSI_MED_REMOVL = $1E ; Prevent/Allow medium Removal (O)
#SCSI_READ6 = $08 ; Read 6-byte (MANDATORY)
#SCSI_READ10 = $28 ; Read 10-byte (MANDATORY)
#SCSI_RD_CAPAC = $25 ; Read Capacity (MANDATORY)
#SCSI_RD_DEFECT = $37 ; Read Defect Data (O)
#SCSI_READ_LONG = $3E ; Read Long (O)
#SCSI_REASS_BLK = $07 ; Reassign Blocks (O)
#SCSI_RCV_DIAG = $1C ; Receive Diagnostic Results (O)
#SCSI_RELEASE = $17 ; Release Unit (MANDATORY)
#SCSI_REZERO = $01 ; Rezero Unit (O)
#SCSI_SRCH_DAT_E = $31 ; Search Data Equal (O)
#SCSI_SRCH_DAT_H = $30 ; Search Data High (O)
#SCSI_SRCH_DAT_L = $32 ; Search Data Low (O)
#SCSI_SEEK6 = $0B ; Seek 6-Byte (O)
#SCSI_SEEK10 = $2B ; Seek 10-Byte (O)
#SCSI_SEND_DIAG = $1D ; Send Diagnostics (MANDATORY)
#SCSI_SET_LIMIT = $33 ; Set Limits (O)
#SCSI_START_STP = $1B ; Start/Stop Unit (O)
#SCSI_SYNC_CACHE = $35 ; Synchronize Cache (O)
#SCSI_VERIFY = $2F ; Verify (O)
#SCSI_WRITE6 = $0A ; Write 6-Byte (MANDATORY)
#SCSI_WRITE10 = $2A ; Write 10-Byte (MANDATORY)
#SCSI_WRT_VERIFY = $2E ; Write and Verify (O)
#SCSI_WRITE_LONG = $3F ; Write Long (O)
#SCSI_WRITE_SAME = $41 ; Write Same (O)
;***************************************************************************
; %%% Commands Unique to Sequential Access Devices %%%
;***************************************************************************
#SCSI_ERASE = $19 ; Erase (MANDATORY)
#SCSI_LOAD_UN = $1B ; Load/Unload (O)
#SCSI_LOCATE = $2B ; Locate (O)
#SCSI_RD_BLK_LIM = $05 ; Read Block Limits (MANDATORY)
#SCSI_READ_POS = $34 ; Read Position (O)
#SCSI_READ_REV = $0F ; Read Reverse (O)
#SCSI_REC_BF_DAT = $14 ; Recover Buffer Data (O)
#SCSI_RESERVE = $16 ; Reserve Unit (MANDATORY)
#SCSI_REWIND = $01 ; Rewind (MANDATORY)
#SCSI_SPACE = $11 ; Space (MANDATORY)
#SCSI_VERIFY_T = $13 ; Verify (Tape) (O)
#SCSI_WRT_FILE = $10 ; Write Filemarks (MANDATORY)
;***************************************************************************
; %%% Commands Unique to Printer Devices %%%
;***************************************************************************
#SCSI_PRINT = $0A ; Print (MANDATORY)
#SCSI_SLEW_PNT = $0B ; Slew and Print (O)
#SCSI_STOP_PNT = $1B ; Stop Print (O)
#SCSI_SYNC_BUFF = $10 ; Synchronize Buffer (O)
;***************************************************************************
; %%% Commands Unique to Processor Devices %%%
;***************************************************************************
#SCSI_RECEIVE = $08 ; Receive (O)
#SCSI_SEND = $0A ; Send (O)
;***************************************************************************
; %%% Commands Unique to Write-Once Devices %%%
;***************************************************************************
#SCSI_MEDIUM_SCN = $38 ; Medium Scan (O)
#SCSI_SRCHDATE10 = $31 ; Search Data Equal 10-Byte (O)
#SCSI_SRCHDATE12 = $B1 ; Search Data Equal 12-Byte (O)
#SCSI_SRCHDATH10 = $30 ; Search Data High 10-Byte (O)
#SCSI_SRCHDATH12 = $B0 ; Search Data High 12-Byte (O)
#SCSI_SRCHDATL10 = $32 ; Search Data Low 10-Byte (O)
#SCSI_SRCHDATL12 = $B2 ; Search Data Low 12-Byte (O)
#SCSI_SET_LIM_10 = $33 ; Set Limits 10-Byte (O)
#SCSI_SET_LIM_12 = $B3 ; Set Limits 10-Byte (O)
#SCSI_VERIFY10 = $2F ; Verify 10-Byte (O)
#SCSI_VERIFY12 = $AF ; Verify 12-Byte (O)
#SCSI_WRITE12 = $AA ; Write 12-Byte (O)
#SCSI_WRT_VER10 = $2E ; Write and Verify 10-Byte (O)
#SCSI_WRT_VER12 = $AE ; Write and Verify 12-Byte (O)
;***************************************************************************
; %%% Commands Unique to CD-ROM Devices %%%
;***************************************************************************
#SCSI_PLAYAUD_10 = $45 ; Play Audio 10-Byte (O)
#SCSI_PLAYAUD_12 = $A5 ; Play Audio 12-Byte 12-Byte (O)
#SCSI_PLAYAUDMSF = $47 ; Play Audio MSF (O)
#SCSI_PLAYA_TKIN = $48 ; Play Audio Track/Index (O)
#SCSI_PLYTKREL10 = $49 ; Play Track Relative 10-Byte (O)
#SCSI_PLYTKREL12 = $A9 ; Play Track Relative 12-Byte (O)
#SCSI_READCDCAP = $25 ; Read CD-ROM Capacity (MANDATORY)
#SCSI_READHEADER = $44 ; Read Header (O)
#SCSI_SUBCHANNEL = $42 ; Read Subchannel (O)
#SCSI_READ_TOC = $43 ; Read TOC (O)
;***************************************************************************
; %%% Commands Unique to Scanner Devices %%%
;***************************************************************************
#SCSI_GETDBSTAT = $34 ; Get Data Buffer Status (O)
#SCSI_GETWINDOW = $25 ; Get Window (O)
#SCSI_OBJECTPOS = $31 ; Object Postion (O)
#SCSI_SCAN = $1B ; Scan (O)
#SCSI_SETWINDOW = $24 ; Set Window (MANDATORY)
;***************************************************************************
; %%% Commands Unique to Optical Memory Devices %%%
;***************************************************************************
#SCSI_UpdateBlk = $3D ; Update Block (O)
;***************************************************************************
; %%% Commands Unique to Medium Changer Devices %%%
;***************************************************************************
#SCSI_EXCHMEDIUM = $A6 ; Exchange Medium (O)
#SCSI_INITELSTAT = $07 ; Initialize Element Status (O)
#SCSI_POSTOELEM = $2B ; Position to Element (O)
#SCSI_REQ_VE_ADD = $B5 ; Request Volume Element Address (O)
#SCSI_SENDVOLTAG = $B6 ; Send Volume Tag (O)
;***************************************************************************
; %%% Commands Unique to Communication Devices %%%
;***************************************************************************
#SCSI_GET_MSG_6 = $08 ; Get Message 6-Byte (MANDATORY)
#SCSI_GET_MSG_10 = $28 ; Get Message 10-Byte (O)
#SCSI_GET_MSG_12 = $A8 ; Get Message 12-Byte (O)
#SCSI_SND_MSG_6 = $0A ; Send Message 6-Byte (MANDATORY)
#SCSI_SND_MSG_10 = $2A ; Send Message 10-Byte (O)
#SCSI_SND_MSG_12 = $AA ; Send Message 12-Byte (O)
;\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
;
; %%% END OF SCSI COMMAND OPCODES %%%
;
;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
;***************************************************************************
; %%% Request Sense Data Format %%%
;***************************************************************************
Structure SENSE_DATA_FMT
ErrorCode.b ; Error Code (70H or 71H)
SegmentNum.b ; Number of current segment descriptor
SenseKey.b ; Sense Key(See bit definitions too)
InfoByte0.b ; Information MSB
InfoByte1.b ; Information MID
InfoByte2.b ; Information MID
InfoByte3.b ; Information LSB
AddSenLen.b ; Additional Sense Length
ComSpecInf0.b ; Command Specific Information MSB
ComSpecInf1.b ; Command Specific Information MID
ComSpecInf2.b ; Command Specific Information MID
ComSpecInf3.b ; Command Specific Information LSB
AddSenseCode.b ; Additional Sense Code
AddSenQual.b ; Additional Sense Code Qualifier
FieldRepUCode.b ; Field Replaceable Unit Code
SenKeySpec15.b ; Sense Key Specific 15th byte
SenKeySpec16.b ; Sense Key Specific 16th byte
SenKeySpec17.b ; Sense Key Specific 17th byte
AddSenseBytes.b ; Additional Sense Bytes
EndStructure
;***************************************************************************
; %%% REQUEST SENSE ERROR CODE %%%
;***************************************************************************
#SERROR_CURRENT = $70 ; Current Errors
#SERROR_DEFERED = $71 ; Deferred Errors
;***************************************************************************
; %%% REQUEST SENSE BIT DEFINITIONS %%%
;***************************************************************************
#SENSE_VALID = $80 ; Byte 0 Bit 7
#SENSE_FILEMRK = $80 ; Byte 2 Bit 7
#SENSE_EOM = $40 ; Byte 2 Bit 6
#SENSE_ILI = $20 ; Byte 2 Bit 5
;***************************************************************************
; %%% REQUEST SENSE SENSE KEY DEFINITIONS %%%
;***************************************************************************
#KEY_NOSENSE = $00 ; No Sense
#KEY_RECERROR = $01 ; Recovered Error
#KEY_NOTREADY = $02 ; Not Ready
#KEY_MEDIUMERR = $03 ; Medium Error
#KEY_HARDERROR = $04 ; Hardware Error
#KEY_ILLGLREQ = $05 ; Illegal Request
#KEY_UNITATT = $06 ; Unit Attention
#KEY_DATAPROT = $07 ; Data Protect
#KEY_BLANKCHK = $08 ; Blank Check
#KEY_VENDSPEC = $09 ; Vendor Specific
#KEY_COPYABORT = $0A ; Copy Abort
#KEY_EQUAL = $0C ; Equal (Search)
#KEY_VOLOVRFLW = $0D ; Volume Overflow
#KEY_MISCOMP = $0E ; Miscompare (Search)
#KEY_RESERVED = $0F ; Reserved
;***************************************************************************
; %%% PERIPHERAL DEVICE TYPE DEFINITIONS %%%
;***************************************************************************
#DTYPE_DASD = $00 ; Disk Device
#DTYPE_SEQD = $01 ; Tape Device
#DTYPE_PRNT = $02 ; Printer
#DTYPE_PROC = $03 ; Processor
#DTYPE_WORM = $04 ; Write-once read-multiple
#DTYPE_CROM = $05 ; CD-ROM device
#DTYPE_CDROM = $05 ; CD-ROM device
#DTYPE_SCAN = $06 ; Scanner device
#DTYPE_OPTI = $07 ; Optical memory device
#DTYPE_JUKE = $08 ; Medium Changer device
#DTYPE_COMM = $09 ; Communications device
#DTYPE_RESL = $0A ; Reserved (low)
#DTYPE_RESH = $1E ; Reserved (high)
#DTYPE_UNKNOWN = $1F ; Unknown or no device type
;***************************************************************************
; %%% ANSI APPROVED VERSION DEFINITIONS %%%
;***************************************************************************
#ANSI_MAYBE = $0 ; Device may or may not be ANSI approved stand
#ANSI_SCSI1 = $1 ; Device complies to ANSI X3.131-1986 (SCSI-1)
#ANSI_SCSI2 = $2 ; Device complies to SCSI-2
#ANSI_RESLO = $3 ; Reserved (low)
#ANSI_RESHI = $7 ; Reserved (high)
Good programmers don't comment their code. It was hard to write, should be hard to read.
@GeoTrail: I just wanted to let you know that I am making progress here. My thanks again to traumatic for his input. 
I've gathered other various pieces of code from here and there, and I hope to put it all together this weekend. With luck, I'll have some working code very soon.
I've gathered other various pieces of code from here and there, and I hope to put it all together this weekend. With luck, I'll have some working code very soon.
What goes around comes around.
PB 5.21 LTS (x86) - Windows 8.1
PB 5.21 LTS (x86) - Windows 8.1
@traumatic:
If I'm not mistaken, I posted the code but it was lost in one of the forum meltdowns last year and I forgot to repost. I could be wrong so I'll check my progress on this when I get home tonight and repost what I have.
To be honest, I forget what my/our objective was here. I'll have to read this thread from the start to refresh my memory.
If I'm not mistaken, I posted the code but it was lost in one of the forum meltdowns last year and I forgot to repost. I could be wrong so I'll check my progress on this when I get home tonight and repost what I have.
To be honest, I forget what my/our objective was here. I'll have to read this thread from the start to refresh my memory.
What goes around comes around.
PB 5.21 LTS (x86) - Windows 8.1
PB 5.21 LTS (x86) - Windows 8.1
Well it appears that my\our goal was to generate an audio cd DiscID. I found this code on my hd, dated 4/24/2005, so I guess this may very well be the code that I posted and was then lost during the forum meltdown last year. Sorry about the lack of commenting, but hey, I barely knew what the hell I was doing at the time as it was. 
I just did some minimal testing on a few audio cd's and compared my DiscID with that of the free app GeoTrail mentioned earlier, found here, and the DiscID's do indeed match. I seem to remember having problems with mixed audio/data cd's, so consider yourself warned in that respect.
Thanks once again to traumatic for his input. The structure/layout of the code could use some refining, so feel free to rip it apart and or optimize as desired.
I just did some minimal testing on a few audio cd's and compared my DiscID with that of the free app GeoTrail mentioned earlier, found here, and the DiscID's do indeed match. I seem to remember having problems with mixed audio/data cd's, so consider yourself warned in that respect.
Thanks once again to traumatic for his input. The structure/layout of the code could use some refining, so feel free to rip it apart and or optimize as desired.
Code: Select all
hASPI32 = OpenLibrary(0, "WNASPI32.DLL")
If hASPI32
*pGetASPI32SupportInfo = IsFunction(0, "GetASPI32SupportInfo" )
If *pGetASPI32SupportInfo
*pSendASPI32Command = IsFunction(0, "SendASPI32Command" )
If *pSendASPI32Command = 0
MessageRequester("Error", "SendASPI32Command not found.")
End
EndIf
Else
MessageRequester("Error", "GetASPI32SupportInfo not found.")
End
EndIf
Else
MessageRequester("Error", "WNASPI32.DLL failed to open.")
End
EndIf
Global hASPI32
Global *pGetASPI32SupportInfo
Global *pSendASPI32Command
Enumeration
#Win_Main
EndEnumeration
Enumeration
#Frame3D_CDROM
#Combo_CDROM
#Frame3D_TOC
#Button_TOC
#List_TOC
#Frame3D_DiscId
#String_DiscId
EndEnumeration
#SENSE_LEN = 14
#DTYPE_DASD = $00 ; Direct-access device (e.g. magnetic disk)
#DTYPE_SEQD = $01 ; Sequential-access device (e.g. magnetic tape)
#DTYPE_PRNT = $02 ; Printer device
#DTYPE_PROC = $03 ; Processor device
#DTYPE_WORM = $04 ; Write-once device (e.g. some optical disks)
#DTYPE_CDROM = $05 ; CD-ROM device
#DTYPE_SCAN = $06 ; Scanner device
#DTYPE_OPTI = $07 ; optical memory device (e.g. some optical disks)
#DTYPE_JUKE = $08 ; Medium changer device (e.g. jukeboxes)
#DTYPE_COMM = $09 ; Communication device
#DTYPE_UNKNOWN = $1F ; Unknown Or no device type
#SC_HA_INQUIRY = 0 ; Queries ASPI For information on specific host adapters.
#SC_GET_DEV_TYPE = 1 ; Requests the SCSI device type For a specific SCSI target.
#SC_EXEC_SCSI_CMD = 2 ; Sends a SCSI command (arbitrary CDB) To a SCSI target.
#SC_ABORT_SRB = 3 ; Requests that ASPI cancel a previously submitted request.
#SC_RESET_DEV = 4 ; Sends a BUS device RESET message To a SCSI target.
#SC_GET_DISK_INFO = 6 ; Returns BIOS information For a SCSI target (Win95 only).
#SC_RESCAN_SCSI_BUS = 7 ; Requests a rescan of a host adapter’s SCSI BUS.
#SC_GETSET_TIMEOUTS = 8 ; Sets SRB timeouts For specific SCSI targets.
#AUDIO_WITH_PREEMPHASIS = 1
#DIGITAL_COPY_PERMITTED = 2
#AUDIO_DATA_TRACK = 4
#TWO_FOUR_CHANNEL_AUDIO = 8
#ADR_NO_MODE_INFORMATION = 0
#ADR_ENCODES_CURRENT_POSITION = 1
#ADR_ENCODES_MEDIA_CATALOG = 2
#ADR_ENCODES_ISRC = 3
#SS_PENDING = 0
#SS_COMP = 1
#SS_ABORTED = 2
#SS_ERR = 4
#SS_INVALID_CMD = $80
#SS_INVALID_HA = $81
#SS_NO_DEVICE = $82
#SS_INVALID_SRB = $E0
#SS_BUFFER_ALIGN = $E1
#SS_ILLEGAL_MODE = $E2
#SS_NO_ASPI = $E3
#SS_FAILED_INIT = $E4
#SS_ASPI_IS_BUSY = $E5
#SS_BUFFER_TO_BIG = $E6
#SS_MISMATCHED_COMPONENTS = $E7
#SS_NO_ADAPTERS = $E8
#SS_INSUFFICIENT_RESOURCES = $E9
#SRB_POSTING = 1
#SRB_ENABLE_RESIDUAL_COUNT = 4
#SRB_DIR_IN = 8
#SRB_DIR_OUT = $10
#SRB_EVENT_NOTIFY = $40
#SCSI_INQUIRY = $12
#SCSI_READ_TOC = $43
#SCSI_TST_U_RDY = 0
#ECD_AUDIO = 16
#ECD_DATA = 20
Structure TOCTRACK
Reserved.b
CTL_ADR.b
TrackNumber.b
Reserved2.b
addr.b[4]
EndStructure
Structure TOC
TOCLength.w ; size of TOC
FirstTrack.b ; first track number
LastTrack.b ; last track before lead-out
tracks.TOCTRACK[100] ; infos on each track
EndStructure
Structure SRB_HAInquiry
SRB_Cmd.b ; // ASPI command code = SC_HA_INQUIRY
SRB_Status.b ; // ASPI command status byte
SRB_HaId.b ; // ASPI host adapter number
SRB_Flags.b ; // Reserved, MUST = 0
SRB_Hdr_Rsvd.l ; // Reserved, MUST = 0
HA_Count.b ; // Number of host adapters present
HA_SCSI_ID.b ; // SCSI ID of host adapter
HA_ManagerId.b[16] ; // String describing the manager
HA_Identifier.b[16] ; // String describing the host adapter
HA_Unique.b[16] ; // Host Adapter Unique parameters
HA_Rsvd1.w ; // Reserved, MUST = 0
EndStructure
Structure SRB_ExecSCSICmd
SRB_Cmd.b ; // ASPI command code = SC_EXEC_SCSI_CMD
SRB_Status.b ; // ASPI command status byte
SRB_HaId.b ; // ASPI host adapter number
SRB_Flags.b ; // ASPI request flags
SRB_Hdr_Rsvd.l ; // Reserved, MUST = 0
SRB_Target.b ; // Target's SCSI ID
SRB_Lun.b ; // Target's LUN number
SRB_Rsvd1.w ; // Reserved for Alignment
SRB_BufLen.l ; // Data Allocation Length
SRB_BufPointer.l ; // Data Buffer Pointer
SRB_SenseLen.b ; // Sense Allocation Length
SRB_CDBLen.b ; // CDB Length
SRB_HaStat.b ; // Host Adapter Status
SRB_TargStat.b ; // Target Status
SRB_PostProc.l ; // Post routine
SRB_Rsvd2.b[20] ; // Reserved, MUST = 0
CDBByte.b[16] ; // SCSI CDB
SenseArea.b[16] ; // Request Sense buffer
EndStructure
Structure SRB_GDEVBlock;
SRB_Cmd.b ; // ASPI command code = SC_GET_DEV_TYPE
SRB_Status.b ; // ASPI command status byte
SRB_HaId.b ; // ASPI host adapter number
SRB_Flags.b ; // Reserved, MUST = 0
SRB_Hdr_Rsvd.l ; // Reserved, MUST = 0
SRB_Target.b ; // Target's SCSI ID
SRB_Lun.b ; // Target's LUN number
SRB_DeviceType.b ; // Target's peripheral device type
SRB_Rsvd1.b ; // Reserved, MUST = 0
EndStructure
Structure CDINFO
Name.s
nHaId.b
nTarget.b
nLun.b
EndStructure
Dim cdDevice.CDINFO(8)
Global *cdTOC.TOC
Global totalTracks
Procedure GetASPI32Support()
result = 1
If *pGetASPI32SupportInfo
hostInfo = CallCFunctionFast(*pGetASPI32SupportInfo)
If hostInfo
hostStatus = hostInfo >>8 &$FF
result = hostInfo &$FF
If hostStatus = #SS_COMP And hostStatus <> #SS_NO_ADAPTERS
;MessageRequester("Info", "Count = " + Str(result))
Else
MessageRequester("Error", "hostStatus")
result = 0
EndIf
Else
MessageRequester("Error", "hostStatus")
result = 0
EndIf
Else
MessageRequester("Error", "*pGetASPI32SupportInfo")
result = 0
EndIf
ProcedureReturn result
EndProcedure
Procedure GetSCSIInfo(adapter, target, lun, buflen, *buffer, cdbLen, scsiCmd, b1, b2, b3, b4, b5, b6, b7, b8)
srbExec.SRB_ExecSCSICmd
hEventSRB.l = CreateEvent_(#Null, #True, #False, #Null)
ZeroMemory_(@srbExec, SizeOf(SRB_ExecSCSICmd))
srbExec\SRB_Cmd = #SC_EXEC_SCSI_CMD
srbExec\SRB_HaId = adapter
srbExec\SRB_Target = target
srbExec\SRB_Lun = lun
srbExec\SRB_Flags = #SRB_DIR_IN | #SRB_EVENT_NOTIFY
srbExec\SRB_BufLen = buflen
srbExec\SRB_BufPointer = *buffer
srbExec\SRB_SenseLen = $0E
srbExec\SRB_CDBLen = cdbLen
srbExec\SRB_PostProc = hEventSRB
srbExec\CDBByte[0] = scsiCmd
srbExec\CDBByte[1] = b1
srbExec\CDBByte[2] = b2
srbExec\CDBByte[3] = b3
srbExec\CDBByte[4] = b4
srbExec\CDBByte[5] = b5
srbExec\CDBByte[6] = b6
srbExec\CDBByte[7] = b7
srbExec\CDBByte[8] = b8
ResetEvent_(hEventSRB)
status = CallCFunctionFast(*pSendASPI32Command, @srbExec)
If status = #SS_PENDING
WaitForSingleObject_(hEventSRB, 5000)
EndIf
CloseHandle_(hEventSRB)
If srbExec\SRB_Status = #SS_COMP
If scsiCmd = #SCSI_READ_TOC
*buf.TOC = *buffer
totalTracks = (*buf\LastTrack - *buf\FirstTrack) + 1
EndIf
result = *buffer
EndIf
ProcedureReturn result
EndProcedure
Procedure GetCDROMDevice(maxHAId)
ct = -1
If *pSendASPI32Command
srbGDEVBlock.SRB_GDEVBlock
For byHaId = 0 To maxHAId - 1
For byTarget = 0 To 7
ZeroMemory_(@srbGDEXBlock, SizeOf(SRB_GDEVBlock))
srbGDEVBlock\SRB_Cmd = #SC_GET_DEV_TYPE
srbGDEVBlock\SRB_HaId = byHaId
srbGDEVBlock\SRB_Target = byTarget
devInfo = CallCFunctionFast(*pSendASPI32Command, @srbGDEVBlock)
If srbGDEVBlock\SRB_Status <> #SS_COMP
Continue
EndIf
If srbGDEVBlock\SRB_DeviceType = #DTYPE_CDROM
ct + 1
cdDevice(ct)\nHaId = srbGDEVBlock\SRB_HaId
cdDevice(ct)\nTarget = srbGDEVBlock\SRB_Target
cdDevice(ct)\nLun = srbGDEVBlock\SRB_Lun
buffer$ = Space(36)
*buf = GetSCSIInfo(cdDevice(ct)\nHaId, cdDevice(ct)\nTarget, cdDevice(ct)\nLun, 36, @buffer$, $A, #SCSI_INQUIRY, 0, 0, 0, 36, 0, 0, 0, 0)
For i = 8 To 35
cdDevice(ct)\Name + Chr(PeekB(*buf+i))
Next i
EndIf
Next byTarget
Next byHaId
Else
MessageRequester("Error", "*pSendASPI32Command")
EndIf
ProcedureReturn 1
EndProcedure
Procedure.l cddb_sum(n)
ret.l = 0
While n > 0
ret = ret + (n % 10)
n = n / 10
Wend
ProcedureReturn ret
EndProcedure
Procedure.s cddb_discid(tot_trks)
t.l = 0
n.l = 0
i.l = 0
While i < tot_trks
*cdTOC\tracks[t]\addr[1]
n + cddb_sum((*cdTOC\tracks[i]\addr[1] * 60) + *cdTOC\tracks[i]\addr[2])
i+1
Wend
t = ((*cdTOC\tracks[tot_trks]\addr[1] * 60) + *cdTOC\tracks[tot_trks]\addr[2]) - ((*cdTOC\tracks[0]\addr[1] * 60) + *cdTOC\tracks[0]\addr[2])
ProcedureReturn Hex(n % $FF << 24 | t << 8 | tot_trks)
EndProcedure
Procedure TestUnitReady(ha, target)
srbExec.SRB_ExecSCSICmd
hEventSRB.l = CreateEvent_(#Null, #True, #False, #Null)
ZeroMemory_(@srbExec, SizeOf (SRB_ExecSCSICmd))
srbExec\SRB_Cmd = #SC_EXEC_SCSI_CMD
srbExec\SRB_HaId = ha
srbExec\SRB_Flags = #SRB_EVENT_NOTIFY
srbExec\SRB_Target = target
srbExec\SRB_SenseLen = #SENSE_LEN
srbExec\SRB_CDBLen = 6
srbExec\SRB_PostProc = hEventSRB
srbExec\CDBByte[0] = #SCSI_TST_U_RDY
ResetEvent_(hEventSRB)
CallCFunctionFast(*pSendASPI32Command, @srbExec)
If srbExec\SRB_Status = #SS_PENDING
WaitForSingleObject_(hEventSRB, 5000)
EndIf
If srbExec\SRB_Status = #SS_COMP
result = 1
Else
result = 0
EndIf
ProcedureReturn result
EndProcedure
Procedure FindCDROM()
If hASPI32
MAX_HA_ID = GetASPI32Support()
GetCDROMDevice(MAX_HA_ID)
ct = 0
While cdDevice(ct)\Name <> ""
AddGadgetItem(#Combo_CDROM, ct, Str(cdDevice(ct)\nHaId) + ":" + Str(cdDevice(ct)\nTarget) + ":" + Str(cdDevice(ct)\nLun) + " " + cdDevice(ct)\Name)
ct + 1
Wend
SetGadgetState(#Combo_CDROM, 0)
ActivateGadget(#Combo_CDROM)
Else
Debug "Error"
EndIf
EndProcedure
If OpenWindow(#Win_Main, 385, 11, 300, 315, #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar , "Audio DiscId") And CreateGadgetList(WindowID(#Win_Main))
Frame3DGadget(#Frame3D_CDROM, 5, 5, 290, 45, "CDROM Drives")
ComboBoxGadget(#Combo_CDROM, 15, 20, 270, 100)
Frame3DGadget(#Frame3D_TOC, 5, 55, 290, 255, "Table of Contents")
ButtonGadget(#Button_TOC, 15, 70, 100, 20, "Get TOC")
ListIconGadget(#List_TOC, 130, 70, 155, 230, "Track", 50)
AddGadgetColumn(#List_TOC, 1, "M:S:F", 100)
Frame3DGadget(#Frame3D_DiscId, 15, 250, 105, 50, "DiscID")
StringGadget(#String_DiscId, 25, 265, 85, 25, "")
FindCDROM()
Quit = #False
Repeat
event = WaitWindowEvent()
Select event
Case #PB_EventGadget
Select EventGadgetID()
Case #Combo_CDROM
ClearGadgetItemList(#List_TOC)
SetGadgetText(#String_DiscId, "")
Case #Button_TOC
ClearGadgetItemList(#List_TOC)
currentCD = GetGadgetState(#Combo_CDROM)
adapter$ = GetGadgetItemText(#Combo_CDROM, currentCD, 0)
ha = Val(StringField(adapter$, 1, ":"))
target = Val(StringField(adapter$, 2, ":"))
If currentCD > -1
If TestUnitReady(ha, target)
buffer.TOC
*cdTOC.TOC = GetSCSIInfo(cdDevice(currentCD)\nHaId, cdDevice(currentCD)\nTarget, cdDevice(currentCD)\nLun, $324, @buffer, $A, #SCSI_READ_TOC, $2, 0, 0, 0, 0, 0, $3, $24)
For t = 0 To totalTracks - 1
If *cdTOC\tracks[t]\CTL_ADR = #ECD_AUDIO
AddGadgetItem(#List_TOC, -1, "Audio " + RSet(Str(*cdTOC\tracks[t]\TrackNumber), 2, "0") + Chr(10) + RSet(Str(*cdTOC\tracks[t]\addr[1]), 2, "0") + ":" + RSet(Str(*cdTOC\tracks[t]\addr[2]), 2, "0") + ":" + RSet(Str(*cdTOC\tracks[t]\addr[3]), 2, "0"))
Else
AddGadgetItem(#List_TOC, -1, "Data " + RSet(Str(*cdTOC\tracks[t]\TrackNumber), 2, "0") + Chr(10) + RSet(Str(*cdTOC\tracks[t]\addr[1]), 2, "0") + ":" + RSet(Str(*cdTOC\tracks[t]\addr[2]), 2, "0") + ":" + RSet(Str(*cdTOC\tracks[t]\addr[3]), 2, "0"))
EndIf
Next t
SetGadgetText(#String_DiscId, RSet(cddb_discid(totalTracks), 8, "0"))
Else
MessageRequester("Error", "Unit not ready." + #CRLF$ + "Please make sure CDROM drive contains a cd.")
EndIf
EndIf
EndSelect
Case #PB_Event_CloseWindow
If hASPI32
CloseLibrary(0)
EndIf
Quit = #True
EndSelect
Until Quit
EndIf
EndWhat goes around comes around.
PB 5.21 LTS (x86) - Windows 8.1
PB 5.21 LTS (x86) - Windows 8.1
-
Michael Korolev
- User

- Posts: 53
- Joined: Wed Nov 01, 2006 3:02 pm
- Location: Russia/Krasnoyarsk
- Contact:
I didn't want to create new topic...
I have yet another problem, run code below. It will give result if you have CD-ROM on SCSI address 0,0,0.
Program fails on line 133 "EndProcedure". I can't understand why. Generally I'm trying to list all CD drives in system, but even can't do it
. Who can trace an error?
Question 2: How I can translate from SCSI address to drive letter?
I have yet another problem, run code below. It will give result if you have CD-ROM on SCSI address 0,0,0.
Code: Select all
#SS_PENDING=$00
#SS_COMP=$01
#SRB_DIR_IN=$08
#SRB_EVENT_NOTIFY=$40
#SENSE_LEN=$0E
#DTYPE_CDROM=$05
#SC_HA_INQUIRY=$00
#SC_GET_DEV_TYPE=$01
#SC_EXEC_SCSI_CMD=$02
Structure SRB_HAInquiry
; HX/DEC
SRB_Cmd.b ; 00/000 ASPI command code = #SC_HA_INQUIRY
SRB_Status.b ; 01/001 ASPI command status byte
SRB_HaId.b ; 02/002 ASPI host adapter number
SRB_Flags.b ; 03/003 ASPI request flags
SRB_Hdr_Rsvd.l ; 04/004 Reserved, MUST = 0
HA_Count.b ; 08/008 Number of host adapters present
HA_SCSI_ID.b ; 09/009 SCSI ID of host adapter
HA_ManagerId.b[16] ; 0A/010 String describing the manager
HA_Identifier.b[16] ; 1A/026 String describing the host adapter
HA_Unique.b[16] ; 2A/042 Host Adapter Unique parameters
HA_Rsvd1.w ; 3A/058 Reserved, MUST = 0
EndStructure
Structure SRB_GDEVBlock
; HX/DEC
SRB_Cmd.b ; 00/000 ASPI command code = #SC_GET_DEV_TYPE
SRB_Status.b ; 01/001 ASPI command status byte
SRB_HaId.b ; 02/002 ASPI host adapter number
SRB_Flags.b ; 03/003 Reserved, MUST = 0
SRB_Hdr_Rsvd.l ; 04/004 Reserved, MUST = 0
SRB_Target.b ; 08/008 Target's SCSI ID
SRB_Lun.b ; 09/009 Target's LUN number
SRB_DeviceType.b ; 0A/010 Target's peripheral device type
SRB_Rsvd1.b ; 0B/011 Reserved, MUST = 0
EndStructure
Structure SRB_ExecSCSICmd
; HX/DEC
SRB_Cmd.b ; 00/000 ASPI command code = #SC_EXEC_SCSI_CMD
SRB_Status.b ; 01/001 ASPI command status byte
SRB_HaId.b ; 02/002 ASPI host adapter number
SRB_Flags.b ; 03/003 ASPI request flags
SRB_Hdr_Rsvd.l ; 04/004 Reserved
SRB_Target.b ; 08/008 Target's SCSI ID
SRB_Lun.b ; 09/009 Target's LUN number
SRB_Rsvd1.w ; 0A/010 Reserved for Alignment
SRB_BufLen.l ; 0C/012 Data Allocation Length
SRB_BufPointer.l ; 10/016 Data Buffer Pointer
SRB_SenseLen.b ; 14/020 Sense Allocation Length
SRB_CDBLen.b ; 15/021 CDB Length
SRB_HaStat.b ; 16/022 Host Adapter Status
SRB_TargStat.b ; 17/023 Target Status
SRB_PostProc.l ; 18/024 Post routine
SRB_Rsvd2.b[20] ; 1C/028 Reserved, MUST = 0
CDBByte.b[16] ; 30/048 SCSI CDB
SenseArea.b[#SENSE_LEN+2] ;50/064 Request Sense buffer
EndStructure
Procedure.b HIBYTE(w.w)
ProcedureReturn (w>>8) & $FF
EndProcedure
Procedure.b LOBYTE(w.w)
ProcedureReturn w &$FF
EndProcedure
Procedure.w HIWORD(l.l)
ProcedureReturn (l>>16) & $FFFF
EndProcedure
Procedure.w LOWORD(l.l)
ProcedureReturn l & $FFFF
EndProcedure
If OpenLibrary(0,".\Wnaspi32.dll")
SupportInfo=CallCFunction(0,"GetASPI32SupportInfo")
ASPIStatus.b=HiByte(LoWord(SupportInfo)); статус ASPI
HACount.b=LoByte(LoWord(SupportInfo)); количество адаптеров
If Not ASPIStatus=#SS_COMP
MessageRequester("Error","ASPI error")
EndIf
EndIf
Structure CDROM
HaID.b; номер адаптера ASPI
Target.b; ID объекта SCSI
Lun.b; логический номер устройства
name$; наша цель
EndStructure
zSRB_HAInquiry.SRB_HAInquiry
zSRB_GDEVBlock.SRB_GDEVBlock
Global zSRB_ExecSCSICmd.SRB_ExecSCSICmd
Global zCdrom.CDROM
Global buffer$=Space(36)
Procedure CdromInfo()
buffer$=Space(36)
*buf=@buffer$
*buffer=*buf
SRB_EventID=CreateEvent_(#Null,#True,#False,#Null)
With zSRB_ExecSCSICmd
\SRB_Cmd=#SC_EXEC_SCSI_CMD
\SRB_HaId=zCdrom\HaID
\SRB_Target=zCdrom\Target
\SRB_Lun=zCdrom\Lun
\SRB_Flags=#SRB_DIR_IN|#SRB_EVENT_NOTIFY
\SRB_BufLen=36
\SRB_BufPointer=@buffer$
\SRB_SenseLen=#SENSE_LEN
\SRB_CDBLen=12
\SRB_PostProc=SRB_EventID
\CDBByte[0]=$12
\CDBByte[4]=31
EndWith
ResetEvent_(SRB_EventID)
CallFunction(0,"SendASPI32Command",zSRB_ExecSCSICmd)
If zSRB_ExecSCSICmd\SRB_Status=#SS_PENDING
WaitForSingleObject_(SRB_EventID,5000); ждём окончания обработки команды
EndIf
CloseHandle_(SRB_EventID)
If zSRB_ExecSCSICmd\SRB_Status=#SS_COMP
For i.b=8 To 30
zCdrom\name$+Chr(PeekB(*buffer+i))
Next
Debug(zCdrom\name$)
Else
MessageRequester("Error","ASPI Error...")
End
EndIf
EndProcedure
; начинаем перебирать все адаптеры
For H.b=0 To HACount-1
; запрос ASPI для получения информации об адаптерах.
zSRB_HAInquiry\SRB_Cmd=#SC_HA_INQUIRY
zSRB_HAInquiry\SRB_HaID=H
CallFunction(0,"SendASPI32Command",zSRB_HAInquiry); посылаем ASPI команду
If zSRB_HAInquiry\SRB_Status=#SS_COMP; если выполнено без ошибок, тогда
; четвёртый байт уникальных параметров определяет максимальное количество объектов SCSI
MaxTgt.b=zSRB_HAInquiry\HA_Unique[3]
If MaxTgt=0; если этот байт равен 0, тогда присваиваем переменной максимально возможное значение (константа MAXTARG=7)
MaxTgt=6
EndIf
MaxLun.b=7
For T.b=0 To MaxTgt-1; начинаем перебирать все объекты SCSI
For L.b=0 To MaxLun-1; и все логические номера устройств
; команда запрашивает тип устройства для объекта SCSI
zSRB_GDEVBlock\SRB_Cmd=#SC_GET_DEV_TYPE
zSRB_GDEVBlock\SRB_HaID=H
zSRB_GDEVBlock\SRB_Target=T
zSRB_GDEVBlock\SRB_Lun =L
CallFunction(0,"SendASPI32Command",zSRB_GDEVBlock)
; если выполнено без ошибок, и устройство является CD-ROM, заполняем переменную Cdroms.
If (zSRB_GDEVBlock\SRB_Status=#SS_COMP) And (zSRB_GDEVBlock\SRB_DeviceType=#DTYPE_CDROM)
zCdrom\HaID=H
zCdrom\Target=T
zCdrom\Lun=L
;получаем информацию об этом CD-ROM
CdromInfo()
EndIf
Next
Next
EndIf
Next
Question 2: How I can translate from SCSI address to drive letter?
Re: Get CD audio track frame?
This code run on 4.4b5
Code: Select all
;/ Adaptec ASPI SDK
;/ http://www.frogaspi.org/download/aspi32.pdf
PrototypeC.l FreeASPI32Buffer(Aspi32buff.l)
PrototypeC.l GetASPI32Buffer(Aspi32buff.l)
PrototypeC.l GetASPI32DLLVersion()
; Bits 0-7 represents the Major Version
; Bits 8-15 represents the Minor Version
; Bits 16-23 represents the Release Version
; Bits 24-31 represents the Build Version
PrototypeC.l GetASPI32SupportInfo()
PrototypeC.l GetDriveHandleByDriveLetter(drive.c)
PrototypeC.l GetDriveHandleByDriveNo(driveNo.b)
PrototypeC.l GetDriveHandleBySCSIAddr(ha.b, id.b, lun.b)
PrototypeC.l GetScsiAddressByCdRomID(id.b)
; Bits 0-7 represents the lun
; Bits 8-15 represents the Target
; Bits 16-23 represents the HostAdapter
PrototypeC.l GetScsiAddressByDriveLetter(drive.c)
; Bits 0-7 represents the lun
; Bits 8-15 represents the Target
; Bits 16-23 represents the HostAdapter
PrototypeC.l HaveAdminPrivilege()
PrototypeC.l RescanSCSI() ; Rescan all devices.
PrototypeC.l SendASPI32Command(ExecSCSIcmd.l)
PrototypeC.l TranslateASPI32Address(D1.l, D2.l)
Global FreeASPI32Buffer.FreeASPI32Buffer
Global GetASPI32Buffer.GetASPI32Buffer
Global GetASPI32DLLVersion.GetASPI32DLLVersion
Global GetASPI32SupportInfo.GetASPI32SupportInfo
Global GetDriveHandleByDriveLetter.GetDriveHandleByDriveLetter
Global GetDriveHandleByDriveNo.GetDriveHandleByDriveNo
Global GetDriveHandleBySCSIAddr.GetDriveHandleBySCSIAddr
Global GetScsiAddressByCdRomID.GetScsiAddressByCdRomID
Global GetScsiAddressByDriveLetter.GetScsiAddressByDriveLetter
Global HaveAdminPrivilege.HaveAdminPrivilege
Global RescanSCSI.RescanSCSI
Global SendASPI32Command.SendASPI32Command
Global TranslateASPI32Address.TranslateASPI32Address
Procedure wnaspi32_Init()
Shared hASPI32.l
;/ http://www.frogaspi.org Frog Aspi is our FREE aspi driver.
hASPI32 = OpenLibrary(#PB_Any, "WNASPI32.DLL")
If hASPI32
FreeASPI32Buffer = GetFunction(hASPI32, "FreeASPI32Buffer")
GetASPI32Buffer = GetFunction(hASPI32, "GetASPI32Buffer")
GetASPI32DLLVersion = GetFunction(hASPI32, "GetASPI32DLLVersion")
GetASPI32SupportInfo = GetFunction(hASPI32, "GetASPI32SupportInfo")
GetDriveHandleByDriveLetter = GetFunction(hASPI32, "GetDriveHandleByDriveLetter")
GetDriveHandleByDriveNo = GetFunction(hASPI32, "GetDriveHandleByDriveNo")
GetDriveHandleBySCSIAddr = GetFunction(hASPI32, "GetDriveHandleBySCSIAddr")
GetScsiAddressByCdRomID = GetFunction(hASPI32, "GetScsiAddressByCdRomID")
GetScsiAddressByDriveLetter = GetFunction(hASPI32, "GetScsiAddressByDriveLetter")
HaveAdminPrivilege = GetFunction(hASPI32, "HaveAdminPrivilege")
RescanSCSI = GetFunction(hASPI32, "RescanSCSI")
SendASPI32Command = GetFunction(hASPI32, "SendASPI32Command")
TranslateASPI32Address = GetFunction(hASPI32, "TranslateASPI32Address")
EndIf
EndProcedure
Procedure wnaspi32_End()
Shared hASPI32.l
CloseLibrary(hASPI32)
EndProcedure

