.
It's not IMAPI but it may help you.
Code: Select all
; =================================================================
;
; Author: Unknown (any idea? I'd like to credit the authors)
; Date: about April 2010
; Explain: Lists the Optical Drives Abilities
;
; Search tips:
;
; Typical Usage:
; =================================================================
; Files assembled from old information by Blueb April 2019
; and made unicode capable.
;
;- Structures required...
Structure t_MMC
PageCode.b ; Page Code 1
PageLen.b ; Page len1
rsvd2.b[8] ; reserved8
ReadSupported.b ; readable formats1
WriteSupported.b; writable formats1
misc.b[4] ; misc. 4
MaxReadCDSpeed.b[2] ; max. read speed 2 0-17
NumVolLevels.b[2] ; num. volume levels2 18-19
BufferSize.b[2] ; buffer size 2
CurrReadCDSpeed.b[2]; curr. read speed2
rsvd.b ; reserved1
misc2.b ; misc. 1
MaxWriteCDRSpeed.b[2] ; max. write speed
CurrWriteSpeed.b[2] ; curr write speed
rsvd3.b[20] ; other
Rest.b[32]
EndStructure
Structure t_SCSI_ADDRESS
Length.i ; data len
PortNumber.b ; Host Adapter
PathId.b ; ?
TargetId.b ; Target
Lun.b ; Logical Unit Number
EndStructure
Structure t_OVERLAPPED
Internal.i ;
InternalHigh.i ;
offset.i ;
OffsetHigh.i ;
hEvent.i ;
EndStructure
Structure t_HAID
HA.b ; Host Adapter
ID.b ; Target
DEV_Lun.b; Target Logical Unit Number
DEV_DeviceType.b ; Devicetype
EndStructure
Structure t_InqDat
PDT.b ; drive type
PDQ.b ; removable drive
ver.b ; MMC Version (zero for ATAPI)
RDF.b ; interface depending field
DLEN.b ; additional len
rsv1.b[2] ; reserved
Feat.b ; ?
VID.b[8] ; vendor
PID.b[16] ; Product
PVER.b[4] ; revision (= Firmware Version)
FWVER.b[21] ; extra data
EndStructure
Structure t_SPTD
Length.w ; data len
ScsiStatus.b ; SCSI Status
PathId.b ; Bus Number
TargetId.b ; Target
Lun.b ; Logical Unit Number
CdbLength.b ; CDB (Command Descriptor Block)
SenseInfoLength.b ; Sense Info len
DataIn.b ; data direction
padding0.b[3]
DataTransferLength.i ; data transfer length
TimeOutValue.i ; command timeout
DataBuffer.i ; Pointer to the data buffer
SenseInfoOffset.i ; Sense Info Offset
Cdb.b[16] ; Command Descriptor Block
Fill.b[3] ;
EndStructure
Structure t_SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER
spt.t_SPTD ; SPTD structure
Fill.i ;
SenseBuffer.b[32] ; Debugging-Info from the drive
EndStructure
Structure t_ReadFeatures
CDR.b ;CD-R
CDRW.b ;CD-RW
DVDROM.b ;DVD-ROM
DVDR.b ;DVD-R
DVDRW.b ;DVD-RW
DVD_R_DL.b ;DVD-R DL
DVD_RW_DL.b ;DVD-RW DL
DVD_P_R.b ;DVD+R
DVD_P_RW.b ;DVD+RW
DVD_P_R_DL.b;DVD+R DL
DVD_P_RW_DL.b ;DVD+RW DL
DVDRAM.b ;DVD-RAM
BD_ROM.b ;Blue_ray_Disk-ROM
BD_R.b ;Blue_ray_Disk-R
BD_RW.b ;Blue_ray_Disk-RW
HD_DVD_ROM.b ;HD DVD-ROM
HD_DVD_R.b ;HD DVD-R
HD_DVD_RAM.b ;HD DVD-RAM
SubChannels.b ;Sub-Channels
SubChannelsCorrected.b ;Sub-Channels corrected
SubChannelsFromLeadIn.b ;Sub-Channels from Lead-In
C2ErrorPointers.b ;C2 Error Pointers
ISRC.b ;International Standard Recording Code
UPC.b ;Universal Product Code
BC.b ;Bar Code
Mode2Form1.b ;Mode 2 Form 1 sectors
Mode2Form2.b ;Mode 2 Form 2
MultiSession.b ;Multi-Session CDs
CDDARawRead.b ;Audio sectors
MultiRead.b
DDCD_Read.b
EndStructure
Structure t_WriteModes
Raw16.b ; Raw + 16
Raw16Test.b ; Raw + 16 + Test-Mode
Raw96P.b ; Raw + 96 with packed R-W subchannels
Raw96R.b ; Raw + 96 with raw R-W subchannels
Raw96PTest.b ; Raw + 96 with packed R-W subchannels + Test-Mode
Raw96RTest.b ; Raw + 96 with raw R-W subchannels + Test-Mode
SAO.b ; Session At Once
SAOR96P.b ; SAO with packed R-W subchannels
SAOR96R.b ; SAO with raw R-W subchannels
SAOTest.b ; Session At Once + Test-Mode
SAOR96PTest.b; SAO with packed R-W subchannels + Test-Mode
SAOR96RTest.b; SAO with raw R-W subchannels + Test-Mode
TAO.b ; Track At Once
TAOTest.b ; Track At Once + Test-Mode
EndStructure
Structure t_WriteFeatures
CDR.b ;CD-R
CDRW.b ;CD-RW
DVDR.b ;DVD-R
DVD_R_DL.b ;DVD-R DL
DVDRW.b ;DVD-RW
DVD_RW_DL.b ;DVD-RW DL
DVD_P_R.b ;DVD+R
DVD_P_R_DL.b;DVD+R DL
DVD_P_RW.b ;DVD+RW
DVD_P_RW_DL.b ;DVD+RW DL
DVDRAM.b ;DVD-RAM
BD_R.b ;Blue_ray_Disk-R
BD_RW.b ;Blue_ray_Disk-RW
HD_DVD_R.b ;HD DVD-R
HD_DVD_RAM.b ;HD DVD-RAM
TestMode.b ;Test-Mode
BURNProof.b ;BURN-Proof
LAYER_JUMP.b ;Layer Jump Recording
CD_TAO.b
Def_Management.b
CDRWCAV_Write.b
MRW.b
DDCDR_Write.b
DDCDRW_Write.b
WriteModes.t_WriteModes ; supported write modes
EndStructure
Structure t_OtherFeats
PowerManagement.b
EmbeddedChanger.b
CDAudioAnalogPlay.b
MicrocodeUpgrade.b
TimeOut.b
RealTimeStreaming.b
LogicalUnitSerialNumber.b
DiscControlBlocks.b
DVD_CSS.b
DVD_CPRM.b
FirmwareDate.b
AnalogAudio.b ; analog audio playback?
JitterCorrection.b ; jitter effect correction?
LockMedia.b ; can lock media?
MRW.b ;Mount Rainier Write
VolumeLevels.l
BufferSize.l
LoadingMechanism.s
DriveInterface.s
EndStructure
Structure t_Speed
MaxRSpeed.i ;max CD read speed
MaxWCDRSpeed.i ;max CDR write speed
CurrRSpeed.i ;current CD read speed
CurrWSpeed.i ;current CDR write speed
MaxWCDRWSpeed.i ;max CDRW write speed
EndStructure
Structure OpticalDriveInfo
VendorID.s; return vendor
ProductID.s ; return product id
Firmware.s ; return firmware version
ExData.s ; extra data
BufferSize.l; buffer size
BusNo.b
TargetNo.b
LunNo.b
ReadFeatures.t_ReadFeatures
WriteFeatures.t_WriteFeatures ; write features
OtherFeatures.t_OtherFeats ; other features
Speeds.t_Speed ; speeds
EndStructure
;- Enumerations...
Enumeration
#SCSI_IOCTL_DATA_OUT ; send data to the drive
#SCSI_IOCTL_DATA_IN ; retrieve data from the drive
#SCSI_IOCTL_DATA_UNSPECIFIED ; no transfer
EndEnumeration
Enumeration
#SRB_DIR_READ = 1
#SRB_DIR_IN = $8 ; retrieve data from the drive
#SRB_DIR_OUT = $10 ; send data to the drive
EndEnumeration
;- Contstants...
Global IOCTL_SCSI_PASS_THROUGH_DIRECT.i = 315412
Global IOCTL_SCSI_GET_ADDRESS.i = 266264
Global Dim Language.s(1); For the feature bit values
Language(0)="NO"
Language(1)="YES"
;- Procedures...
Procedure.i GetDriveHandle(drv.s)
;get the handle with CreateFile().
;you can access drives with "\\.\X:", where X is the drive's char.
ProcedureReturn CreateFile_("\\.\" + drv + ":", #GENERIC_READ | #GENERIC_WRITE, #FILE_SHARE_READ | #FILE_SHARE_WRITE, 0, #OPEN_EXISTING, #FILE_ATTRIBUTE_NORMAL,0)
EndProcedure
Procedure.i SPTIAvailable()
pswb.t_SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER: OL.t_OVERLAPPED
Length.l: returned.l: i.l
status.l:drv.s
;find the first CD/DVD-ROM drive
For i = 1 To 26
If GetDriveType_(Chr(i + 64) + ":") = 5
drv = Chr(i + 64)
Break
EndIf
Next
;get its drive handle
fh.i = GetDriveHandle(drv)
If fh = 0: ProcedureReturn 0: EndIf
With pswb\spt
\senseInfoOffset = OffsetOf(t_SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER\SenseBuffer) ; Sense Info Offset
\senseInfoLength = SizeOf(pswb\SenseBuffer)-1 ; Sense Info size
\DataIn = #SCSI_IOCTL_DATA_IN ; data direction
\TimeOutValue = 10 ; Timeout
\CdbLength = 6 ; CDB length
\length = 44 ; size of the substructure
EndWith
Length = SizeOf(pswb) ; size of the structure
status = DeviceIoControl_(fh, IOCTL_SCSI_PASS_THROUGH_DIRECT, @pswb, Length, @pswb, Length, @returned, @OL)
;success?
If status = 1
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndProcedure
;HA:ID from drive char (NT/2K/XP)
Procedure.i SPTIGetHAID(strDrv.s, *haid.t_HAID)
returned.l: status.l
i.l
sd.SECURITY_ATTRIBUTES
pscsiAddr.t_SCSI_ADDRESS
OL.t_OVERLAPPED
;get drive handle
fh.i = GetDriveHandle(strDrv)
If fh = 0: ProcedureReturn 0: EndIf
pscsiAddr\Length = SizeOf(pscsiAddr)
status = DeviceIoControl_(fh, IOCTL_SCSI_GET_ADDRESS, @pscsiAddr, SizeOf(pscsiAddr), @pscsiAddr, SizeOf(pscsiAddr), @returned, @OL)
CloseHandle_(fh)
;success?
If status = 1
With pscsiAddr
*haid\HA = \PortNumber
*haid\ID = \TargetId
ProcedureReturn 1
EndWith
Else
ProcedureReturn 0
EndIf
EndProcedure
;execute a command through the SPTI
Procedure.i SPTICmd(drv.s, Array cmd.b(1), CmdLen.w, WFE.l, eDir.l, Pointer.l, PointerLen.l, Timeout.i = 5)
pswb.t_SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER: OL.t_OVERLAPPED
Length.l: returned.l: i.l
status.l
;get the drive's handle
fh.i = GetDriveHandle(drv)
If fh = 0: ProcedureReturn 0: EndIf
;check the timeout
If WFE: Timeout = 9999: ElseIf Timeout = 0: Timeout = 10: EndIf
With pswb\spt
\length = 44 ; size of the substructure
\DataIn = eDir ; data dir
\TimeOutValue = Timeout ; Timeout
\senseInfoLength = SizeOf(pswb\SenseBuffer)-1 ; Sense Info size
\senseInfoOffset = OffsetOf(t_SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER\SenseBuffer) ; Sense Info Offset
\DataTransferLength = PointerLen ; data len
\DataBuffer = Pointer ; data buffer pointer
For i = 0 To CmdLen - 1
\Cdb[i] = cmd(i)
Next i ; CDB from Array
\CdbLength = CmdLen ; CDB len
EndWith
Length = SizeOf(pswb) ; size of the structure
;SPTD
status = DeviceIoControl_(fh, IOCTL_SCSI_PASS_THROUGH_DIRECT, @pswb, Length, @pswb, Length, @returned, @OL)
;close the drive's handle
CloseHandle_(fh)
;success?
If status = 1 And pswb\spt\ScsiStatus = 0
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndProcedure
; -------------------------------------------------------
Procedure.i ExecCMD(DrvID.s, Array cmd.b(1), CmdLen.w, WFE.l, eDir.l, BufPtr.l, buflen.l, Timeout.i = 5)
DataDir.l
If eDir = #SRB_DIR_IN
DataDir = #SCSI_IOCTL_DATA_IN
Else
DataDir = #SCSI_IOCTL_DATA_OUT
EndIf
ProcedureReturn SPTICmd(DrvID, cmd(), CmdLen, WFE, DataDir, BufPtr, buflen, Timeout)
EndProcedure
;Read a Mode Page
Procedure.i CDRomModeSense10(DrvID.s, MP.b, PtrBuffer.l, BufferLen.l)
Dim cmd.b(9)
cmd(0) = $5A ; ' MODE SENSE 10 OpCode
cmd(2) = MP & $3F ;' Mode Page
cmd(7) = BufferLen >> 8 ; ' allocation length
cmd(8) = BufferLen & $FF ; ' allocation length
ProcedureReturn ExecCMD(DrvID, cmd(), 10, #False, #SRB_DIR_IN, PtrBuffer, BufferLen + 1)
EndProcedure
;send a Mode Page
Procedure.i CDRomModeSelect10(DrvID.s, PtrBuffer.l, BufferLen.l)
Dim cmd.b(9)
cmd(0) = $55 ; MODE SELECT10 OpCode
cmd(1) = $10 ; PF = 1 (Page Format)
cmd(7) = (BufferLen >> 8) & $FF ; allocation length
cmd(8) = BufferLen & $FF ; allocation length
ProcedureReturn ExecCMD(DrvID, cmd(), 10, #True, #SRB_DIR_OUT, PtrBuffer, BufferLen)
EndProcedure
;send new write parameters page
Procedure.i CDRomWriteParams(strDrv.s, TestMode.l, BURNProof.l, TrackPause.l, WriteType.b, TrackMode.b, DataBlockType.b, MultiSession.l)
Dim bufData.b(60)
PS.b
i.w
bufData(1) = 58 ; length
bufData(8) = 5 ; Page Code
bufData(9) = $32 ; Page length
;WriteType, Test-Mode and Burn Proof
bufData(10) = WriteType | (TestMode * $10) | (BURNProof * $40)
;Track-Mode, Multi-Session
bufData(11) = TrackMode | (MultiSession * $C0)
;Data-Mode (Mode 1: 2048 Bytes User-Data)
bufData(12) = DataBlockType
;Track Pause: 150 sectors (frames) = 2 seconds
bufData(22) = (TrackPause >> 8) & $FF
bufData(23) = TrackPause & $FF
;send new WPP
ProcedureReturn CDRomModeSelect10(strDrv, @bufData(), 60)
EndProcedure
;Read Drive Features
Procedure.i ReadDriveAttributes(DrvID.s, Exec_Command.l, Exec_len.l, PtrBuffer.l, BufferLen.l)
Dim cmd.b(11)
Exec_Command2.l
cmd(0) = $46
cmd(1) = 2
cmd(9) = 0
If Exec_Command > 255
Exec_Command2 = 1
Exec_Command & $FF
EndIf
cmd(2) = Exec_Command2
cmd(3) = Exec_Command
cmd(4) = 0
cmd(5) = 0
cmd(6) = 0
cmd(7) = 0
cmd(8) = Exec_len
ProcedureReturn ExecCMD(DrvID, cmd(), 12, #True, #SRB_DIR_IN, PtrBuffer, BufferLen, 10)
EndProcedure
Procedure.i From4Byte(Array header.b(1))
ProcedureReturn (header(0) << 24) | (header(1) << 16) | (header(2) << 8) | header(3)
EndProcedure
;Read drive features
Procedure.i CDRomGetConfiguration(strDrv.s, StartFeature.b, RT.b, PtrBuffer.l, buflen.l)
Dim cmd.b(9)
cmd(0) = $46 ; GET CONFIGURATION Op-Code
cmd(1) = RT ; RT Byte
cmd(2) = (StartFeature >> 8) & $FF ; start feature
cmd(3) = StartFeature & $FF ; start feature
cmd(7) = (buflen >> 8) & $FF ; allocation length
cmd(8) = buflen & $FF ; allocation length
ProcedureReturn ExecCMD(strDrv, cmd(), 10, #False, #SRB_DIR_IN, PtrBuffer, buflen + 1, 10)
EndProcedure
Procedure.s CDRomGetInterface(strDrv.s)
Dim buffer.b(15): Dim cmd.b(9)
inquiry.t_InqDat
;try to read the drive's core feature
CDRomGetConfiguration(strDrv, 1, 2, @buffer(), ArraySize(buffer()))
;determine the interface from it
tmp.i = (buffer(12) << 24) | (buffer(13) << 16) | (buffer(14) << 8) | buffer(15)
Select tmp
Case 0: ProcedureReturn "VIRTUAL"
Case 1: ProcedureReturn "SCSI"
Case 2: ProcedureReturn "ATAPI"
Case 3, 4: ProcedureReturn "IEEE"
Case 7: ProcedureReturn "SATA"
EndSelect
;if it didn't work, try INQUIRY
cmd(0) = $12 ; Inquiry OpCode
cmd(4) = SizeOf(inquiry) - 1 ; allocation length
If ExecCMD(strDrv, cmd(), 10, #False, #SRB_DIR_IN, @inquiry, SizeOf(inquiry), 10)
If inquiry\ver = 0: ProcedureReturn "ATAPI": EndIf
If inquiry\ver >= 2: ProcedureReturn "VIRTUAL": EndIf
EndIf
ProcedureReturn "UNKNOWN"
EndProcedure
Procedure GetOpticalDriveInfo(strDrvID.s, *DriveInfo.OpticalDriveInfo)
aa.t_HAID
SPTIGetHAID(strDrvID,@aa)
*DriveInfo\BusNo = aa\HA
*DriveInfo\TargetNo = aa\ID
*DriveInfo\LunNo = aa\DEV_Lun
inq.t_InqDat ; Inquiry structure
Dim cmd.b(5) ; CDB
cmd(0) = $12 ; 0x12 Inquiry (6 Byte)
cmd(4) = SizeOf(inq) - 1 ; allocation length
;execute the command (inquiry needs to be supported by every CD/DVD-ROM)
ExecCMD(strDrvID, cmd(), 6, #True, #SRB_DIR_IN, @inq, SizeOf(inq))
; -------------------------------------------------------
; modified the following for PureBasic > 5.46
;was... *DriveInfo\VendorID = PeekS(@inq\VID,8);StrConv(inq.VID, vbUnicode)
; -------------------------------------------------------
*DriveInfo\VendorID = PeekS(@inq\VID,-1, #PB_Ascii)
*DriveInfo\ProductID = PeekS(@inq\PID,-1, #PB_Ascii)
*DriveInfo\Firmware = PeekS(@inq\PVER,-1, #PB_Ascii)
*DriveInfo\ExData = PeekS(@inq\FWVER,-1, #PB_Ascii)
;take features
mmc.t_MMC
CDRomModeSense10(strDrvID, $2A, @mmc, SizeOf(mmc) - 1)
With *DriveInfo\ReadFeatures
\CDR = mmc\ReadSupported & 1
\CDRW = (mmc\ReadSupported >> 1) & 1
\DVDROM = (mmc\ReadSupported >> 3) & 1
\DVDR = (mmc\ReadSupported >> 4) & 1
\DVDRW = (mmc\ReadSupported >> 4) & 1; I didn't find a way to determine it, but I do not think that there is a device that can read DVD-R and not DVD-RW. So, if DVD-R can be read, DVD-RW can be read too.
\DVDRAM = (mmc\ReadSupported >> 5) & 1
\CDDARawRead = (mmc\misc[1] >> 0) & 1
\Mode2Form1 = (mmc\misc[0] >> 4) & 1
\Mode2Form2 = (mmc\misc[0] >> 5) & 1
\MultiSession = (mmc\misc[0] >> 6) & 1
\ISRC = (mmc\misc[1] >> 5) & 1
\UPC = (mmc\misc[1] >> 6) & 1
\BC = (mmc\misc[1] >> 7) & 1
\SubChannels = (mmc\misc[1] >> 2) & 1
\SubChannelsCorrected = (mmc\misc[1] >> 3) & 1
\SubChannelsFromLeadIn = (mmc\misc[3] >> 5) & 1
\C2ErrorPointers = (mmc\misc[1] >> 4) & 1
EndWith
;some write features
With *DriveInfo\WriteFeatures
\CDR = (mmc\WriteSupported >> 0) & 1
\CDRW = (mmc\WriteSupported >> 1) & 1
\TestMode = (mmc\WriteSupported >> 2) & 1
\DVDR = (mmc\WriteSupported >> 4) & 1
\DVDRAM = (mmc\WriteSupported >> 5) & 1
\BURNProof = (mmc\misc[0] >> 7) & 1
EndWith
With *DriveInfo\Speeds
\MaxRSpeed = (mmc\MaxReadCDSpeed[0] << 8) | mmc\MaxReadCDSpeed[1]
\CurrRSpeed = (mmc\CurrReadCDSpeed[0] << 8) | mmc\CurrReadCDSpeed[1]
\MaxWCDRSpeed = (mmc\MaxWriteCDRSpeed[0] << 8) | mmc\MaxWriteCDRSpeed[1]
\CurrWSpeed = (mmc\CurrWriteSpeed[0] << 8) | mmc\CurrWriteSpeed[1]
If \CurrRSpeed > \MaxRSpeed: \CurrRSpeed = \MaxRSpeed:EndIf
If \CurrWSpeed > \MaxWCDRSpeed: \CurrWSpeed = \MaxWCDRSpeed: EndIf
EndWith
;the rest of reading and writing features need extra command executions
With *DriveInfo\WriteFeatures
Dim header.b(127): ar.w
; WRITE: DVD-R, DVD-RW, DVD-R DL
ReadDriveAttributes(strDrvID, $2F, 16, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 12
\DVDR = #True
If (header(12) & 2) = 2: \DVDRW = #True:EndIf
If (header(12) & 4) = 4: \DVD_R_DL = #True: EndIf
EndIf
;WRITE: DVD-R DL
ReadDriveAttributes(strDrvID, $33, 16, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 12
\LAYER_JUMP = #True
\DVD_R_DL = #True
EndIf
;WRITE: DVD+R, READ: DVD+R
ReadDriveAttributes(strDrvID, $2B, 16, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 12
*DriveInfo\ReadFeatures\DVD_P_R = #True
If (header(12) & 1) = 1: \DVD_P_R = #True: EndIf
EndIf
;WRITE: DVD+RW, READ: DVD+RW
ReadDriveAttributes(strDrvID, $2A, 16, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 12
*DriveInfo\ReadFeatures\DVD_P_RW = #True
If (header(12) & 1) = 1: \DVD_P_RW = #True: EndIf
EndIf
;WRITE:DVD+R DL, READ: DVD+R DL
ReadDriveAttributes(strDrvID, $3B, 16, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 12
*DriveInfo\ReadFeatures\DVD_P_R_DL = #True
If (header(12) & 1) = 1: \DVD_P_R_DL = #True: EndIf
EndIf
;WRITE: DVD+RW DL, READ: DVD+RW DL
ReadDriveAttributes(strDrvID, $3A, 16, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 12
*DriveInfo\ReadFeatures\DVD_P_RW_DL = #True
If (header(12) & 1) = 1: \DVD_P_RW_DL = #True: EndIf
EndIf
;Blue Ray WRITE
ReadDriveAttributes(strDrvID, $41, 32, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 28
If (header(16) Or header(17) Or header(18) Or header(19) Or header(20) Or header(21) Or header(22) Or header(23))
\BD_R = #True
EndIf
If (header(24) Or header(25) Or header(26) Or header(27) Or header(28) Or header(29) Or header(30) Or header(31))
\BD_RW = #True
EndIf
EndIf
;Blue Ray READ
ReadDriveAttributes(strDrvID, $40, 40, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 36
If (header(16) Or header(17) Or header(18) Or header(19) Or header(20) Or header(21) Or header(22) Or header(23))
*DriveInfo\ReadFeatures\BD_RW = #True
EndIf
If (header(24) Or header(25) Or header(26) Or header(27) Or header(28) Or header(29) Or header(30) Or header(31))
*DriveInfo\ReadFeatures\BD_R = #True
EndIf
If (header(32) Or header(33) Or header(34) Or header(35) Or header(36) Or header(37) Or header(38) Or header(39))
*DriveInfo\ReadFeatures\BD_ROM = #True
EndIf
EndIf
;HD DVD READ
ReadDriveAttributes(strDrvID, $50, 16, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 12
*DriveInfo\ReadFeatures\HD_DVD_ROM = #True
If (header(12) & 1): *DriveInfo\ReadFeatures\HD_DVD_R = #True: EndIf
If (header(14) & 1): *DriveInfo\ReadFeatures\HD_DVD_RAM = #True: EndIf
EndIf
;HD DVD WRITE
ReadDriveAttributes(strDrvID, $51, 16, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 12
If (header(12) & 1): \HD_DVD_R = #True: EndIf
If (header(14) & 1): \HD_DVD_RAM = #True: EndIf
EndIf
;other features
;CD Track At Once
ReadDriveAttributes(strDrvID, $2D, 16, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 8
\CD_TAO = #True
EndIf
;Defect Management
ReadDriveAttributes(strDrvID, $24, 16, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 8
\Def_Management = #True
EndIf
;Multi Read
ReadDriveAttributes(strDrvID, $1D, 16, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 8
*DriveInfo\ReadFeatures\MultiRead = #True
EndIf
;CD-RW CAV write
ReadDriveAttributes(strDrvID, $27, 16, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 8
\CDRWCAV_Write = #True
EndIf
;Mount Rainier Write
ReadDriveAttributes(strDrvID, $28, 16, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 8
\MRW = #True
EndIf
;DDCD read
ReadDriveAttributes(strDrvID, $30, 16, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 8
*DriveInfo\ReadFeatures\DDCD_Read = #True
EndIf
;DDCD-R write
ReadDriveAttributes(strDrvID, $31, 16, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 8
\DDCDR_Write = #True
EndIf
;DDCD-RW write
ReadDriveAttributes(strDrvID, $32, 16, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 8
\DDCDRW_Write = #True
EndIf
;power management
ReadDriveAttributes(strDrvID, $100, 12, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 8
*DriveInfo\OtherFeatures\PowerManagement = #True
EndIf
;embedded changer
ReadDriveAttributes(strDrvID, $102, 12, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 8
*DriveInfo\OtherFeatures\EmbeddedChanger = #True
EndIf
;CD Audio Analog Play
ReadDriveAttributes(strDrvID, $103, 12, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 8
*DriveInfo\OtherFeatures\CDAudioAnalogPlay = #True
EndIf
;Microcode Upgrade
ReadDriveAttributes(strDrvID, $104, 12, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 8
*DriveInfo\OtherFeatures\MicrocodeUpgrade = #True
EndIf
;TimeOut
ReadDriveAttributes(strDrvID, $105, 12, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 8
*DriveInfo\OtherFeatures\TimeOut = #True
EndIf
;DVD CSS
ReadDriveAttributes(strDrvID, $106, 12, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 8
*DriveInfo\OtherFeatures\DVD_CSS = #True
EndIf
;Real Time Streaming
ReadDriveAttributes(strDrvID, $107, 12, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 8
*DriveInfo\OtherFeatures\RealTimeStreaming = #True
EndIf
;Logical Unit Serial Number
ReadDriveAttributes(strDrvID, $108, 12, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 8
*DriveInfo\OtherFeatures\LogicalUnitSerialNumber = #True
EndIf
;Disc Control Blocks
ReadDriveAttributes(strDrvID, $10A, 12, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 8
*DriveInfo\OtherFeatures\DiscControlBlocks = #True
EndIf
;DVD CPRM
ReadDriveAttributes(strDrvID, $10B, 12, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 8
*DriveInfo\OtherFeatures\DVD_CPRM = #True
EndIf
;Firmware Date
ReadDriveAttributes(strDrvID, $10C, 12, @header(), ArraySize(header())+1)
If From4Byte(header()) >= 8
*DriveInfo\OtherFeatures\FirmwareDate = #True
EndIf
EndWith
With *DriveInfo\OtherFeatures
\LockMedia = mmc\misc[2] & 1
\AnalogAudio = mmc\misc[0] & 1
\JitterCorrection = (mmc\misc[1] >> 1) & 1
\BufferSize = (mmc\BufferSize[0] << 8) | mmc\BufferSize[1]
\VolumeLevels = (mmc\NumVolLevels[0] << 8) | mmc\NumVolLevels[1]
Select (mmc\misc[2] >> 5) & 7
Case 0
\LoadingMechanism = "Caddy"
Case 1
\LoadingMechanism = "Tray"
Case 2
\LoadingMechanism = "Popup"
Case 4, 5
\LoadingMechanism = "Changer"
Default
\LoadingMechanism = "Unknown"
EndSelect
EndWith
;writing modes
With *DriveInfo\WriteFeatures
If CDRomWriteParams(strDrvID, #False, #False, 150, 1, 4, 8, #False)
\WriteModes\TAO = #True
EndIf
If CDRomWriteParams(strDrvID, #True, #False, 150, 1, 4, 8, #False)
\WriteModes\TAOTest = #True
EndIf
If CDRomWriteParams(strDrvID, #False, #False, 150, 2, 0, 0, #False)
\WriteModes\SAO = #True
EndIf
If CDRomWriteParams(strDrvID, #True, #False, 150, 2, 0, 0, #False)
\WriteModes\SAOTest = #True
EndIf
If CDRomWriteParams(strDrvID, #False, #False, 150, 2, 0, 2, #False)
\WriteModes\SAOR96P = #True
EndIf
If CDRomWriteParams(strDrvID, #True, #False, 150, 2, 0, 2, #False)
\WriteModes\SAOR96PTest = #True
EndIf
If CDRomWriteParams(strDrvID, #False, #False, 150, 2, 0, 3, #False)
\WriteModes\SAOR96R = #True
EndIf
If CDRomWriteParams(strDrvID, #True, #False, 150, 2, 0, 3, #False)
\WriteModes\SAOR96RTest = #True
EndIf
If CDRomWriteParams(strDrvID, #False, #False, 150, 3, 0, 1, #False)
\WriteModes\Raw16 = #True
EndIf
If CDRomWriteParams(strDrvID, #True, #False, 150, 3, 0, 1, #False)
\WriteModes\Raw16Test = #True
EndIf
If CDRomWriteParams(strDrvID, #False, #False, 150, 3, 0, 2, #False)
\WriteModes\Raw96P = #True
EndIf
If CDRomWriteParams(strDrvID, #True, #False, 150, 3, 0, 2, #False)
\WriteModes\Raw96PTest = #True
EndIf
If CDRomWriteParams(strDrvID, #False, #False, 150, 3, 0, 3, #False)
\WriteModes\Raw96R = #True
EndIf
If CDRomWriteParams(strDrvID, #True, #False, 150, 3, 0, 3, #False)
\WriteModes\Raw96RTest = #True
EndIf
EndWith
;get drive interface
*DriveInfo\OtherFeatures\DriveInterface = CDRomGetInterface(strDrvID)
EndProcedure
Procedure ShowTheInfo(drive.l)
ClearGadgetItems(0)
GetOpticalDriveInfo(GetGadgetItemText(1,GetGadgetState(1)), @DriveInfo.OpticalDriveInfo)
AddGadgetItem(0,-1,"Manufacturer"+Chr(10)+DriveInfo\VendorID)
AddGadgetItem(0,-1,"Device name"+Chr(10)+DriveInfo\ProductID)
AddGadgetItem(0,-1,"Firmware"+Chr(10)+DriveInfo\Firmware)
AddGadgetItem(0,-1,"Extra data"+Chr(10)+DriveInfo\ExData)
AddGadgetItem(0,-1,"Buffer Size"+Chr(10)+Str(DriveInfo\Otherfeatures\BufferSize) + " KB")
AddGadgetItem(0,-1,"Loading Mechanism"+Chr(10)+DriveInfo\Otherfeatures\LoadingMechanism)
AddGadgetItem(0,-1,"Drive Interface"+Chr(10)+DriveInfo\Otherfeatures\DriveInterface)
AddGadgetItem(0,-1,"Connected at"+Chr(10)+"Bus = " + Str(DriveInfo\BusNo)+ " , Target = " + Str(DriveInfo\TargetNo) + " , LUN = " + Str(DriveInfo\LunNo))
AddGadgetItem(0,-1,"Reading/writing Speeds")
SetGadgetItemColor(0, CountGadgetItems(0)-1, #PB_Gadget_FrontColor, $FF0000, 0)
AddGadgetItem(0,-1,"Current CD read speed"+Chr(10)+Str(DriveInfo\Speeds\CurrRSpeed) + " KB/s (" + Str(DriveInfo\Speeds\CurrRSpeed / 176)+ "x)")
AddGadgetItem(0,-1,"Maximum CD read speed"+Chr(10)+Str(DriveInfo\Speeds\MaxRSpeed) + " KB/s (" + Str(DriveInfo\Speeds\MaxRSpeed / 176)+ "x)")
AddGadgetItem(0,-1,"Current CD write speed"+Chr(10)+Str(DriveInfo\Speeds\CurrWSpeed) + " KB/s (" + Str(DriveInfo\Speeds\CurrWSpeed / 176)+ "x)")
AddGadgetItem(0,-1,"Maximum CD write speed"+Chr(10)+Str(DriveInfo\Speeds\MaxWCDRSpeed) + " KB/s (" + Str(DriveInfo\Speeds\MaxWCDRSpeed / 176)+ "x)")
AddGadgetItem(0,-1,"Reading Features")
SetGadgetItemColor(0, CountGadgetItems(0)-1, #PB_Gadget_FrontColor, $FF0000, 0)
With DriveInfo\Readfeatures
AddGadgetItem(0,-1,"CD-R"+Chr(10)+Language(\CDR))
AddGadgetItem(0,-1,"CD-RW"+Chr(10)+Language(\CDRW))
AddGadgetItem(0,-1,"DVD-ROM"+Chr(10)+Language(\DVDROM))
AddGadgetItem(0,-1,"DVD-RAM"+Chr(10)+Language(\DVDRAM))
AddGadgetItem(0,-1,"DVD-R"+Chr(10)+Language(\DVDR))
AddGadgetItem(0,-1,"DVD-RW"+Chr(10)+Language(\DVDRW))
AddGadgetItem(0,-1,"DVD+R"+Chr(10)+Language(\DVD_P_R))
AddGadgetItem(0,-1,"DVD+R DL"+Chr(10)+Language(\DVD_P_R_DL))
AddGadgetItem(0,-1,"DVD+RW"+Chr(10)+Language(\DVD_P_RW))
AddGadgetItem(0,-1,"BD ROM"+Chr(10)+Language(\BD_ROM))
AddGadgetItem(0,-1,"BD-R"+Chr(10)+Language(\BD_R))
AddGadgetItem(0,-1,"BD_RW"+Chr(10)+Language(\BD_RW))
AddGadgetItem(0,-1,"HD DVD-ROM"+Chr(10)+Language(\HD_DVD_ROM))
AddGadgetItem(0,-1,"HD DVD-RAM"+Chr(10)+Language(\HD_DVD_RAM))
AddGadgetItem(0,-1,"HD DVD-R"+Chr(10)+Language(\HD_DVD_R))
AddGadgetItem(0,-1,"CDDA Raw"+Chr(10)+Language(\CDDARawRead))
AddGadgetItem(0,-1,"Mode2 Form1"+Chr(10)+Language(\Mode2Form1))
AddGadgetItem(0,-1,"Mode2 Form2"+Chr(10)+Language(\Mode2Form2))
AddGadgetItem(0,-1,"Multisession"+Chr(10)+Language(\MultiSession))
AddGadgetItem(0,-1,"International Standard Recording Code"+Chr(10)+Language(\ISRC))
AddGadgetItem(0,-1,"Universal Product Code"+Chr(10)+Language(\UPC))
AddGadgetItem(0,-1,"Barcode"+Chr(10)+Language(\BC))
AddGadgetItem(0,-1,"Subchannels"+Chr(10)+Language(\SubChannels))
AddGadgetItem(0,-1,"Subchannels corrected"+Chr(10)+Language(\SubChannelsCorrected))
AddGadgetItem(0,-1,"Subchannels from lead in"+Chr(10)+Language(\SubChannelsFromLeadIn))
AddGadgetItem(0,-1,"C2 error pointers"+Chr(10)+Language(\C2ErrorPointers))
AddGadgetItem(0,-1,"Multi Read"+Chr(10)+Language(\MultiRead))
AddGadgetItem(0,-1,"Double Density Compact Disc (DDCD)"+Chr(10)+Language(\DDCD_Read))
EndWith
AddGadgetItem(0,-1,"Writing Features")
SetGadgetItemColor(0, CountGadgetItems(0)-1, #PB_Gadget_FrontColor, $FF0000, 0)
With DriveInfo\Writefeatures
AddGadgetItem(0,-1,"CD-R"+Chr(10)+Language(\CDR))
AddGadgetItem(0,-1,"CD-RW"+Chr(10)+Language(\CDRW))
AddGadgetItem(0,-1,"DVD-RAM"+Chr(10)+Language(\DVDRAM))
AddGadgetItem(0,-1,"DVD-R"+Chr(10)+Language(\DVDR))
AddGadgetItem(0,-1,"DVD-R DL"+Chr(10)+Language(\DVD_R_DL))
AddGadgetItem(0,-1,"DVD+R"+Chr(10)+Language(\DVD_P_R))
AddGadgetItem(0,-1,"DVD+R DL"+Chr(10)+Language(\DVD_P_R_DL))
AddGadgetItem(0,-1,"DVD-RW"+Chr(10)+Language(\DVDRW))
AddGadgetItem(0,-1,"DVD+RW"+Chr(10)+Language(\DVD_P_RW))
AddGadgetItem(0,-1,"DVD+RW DL"+Chr(10)+Language(\DVD_P_RW_DL))
AddGadgetItem(0,-1,"BD-R"+Chr(10)+Language(\BD_R))
AddGadgetItem(0,-1,"BD-RE"+Chr(10)+Language(\BD_RW))
AddGadgetItem(0,-1,"HD DVD-R"+Chr(10)+Language(\HD_DVD_R))
AddGadgetItem(0,-1,"HD DV-RAM"+Chr(10)+Language(\HD_DVD_RAM))
AddGadgetItem(0,-1,"Test Mode"+Chr(10)+Language(\TestMode))
AddGadgetItem(0,-1,"Burn Proof"+Chr(10)+Language(\BURNProof))
AddGadgetItem(0,-1,"Layer Jump Recording"+Chr(10)+Language(\LAYER_JUMP))
AddGadgetItem(0,-1,"CD TAO"+Chr(10)+Language(\CD_TAO))
AddGadgetItem(0,-1,"Defect Management"+Chr(10)+Language(\Def_Management))
AddGadgetItem(0,-1,"CDRW CAV"+Chr(10)+Language(\CDRWCAV_Write))
AddGadgetItem(0,-1,"Mount Rainier Write (MRW)"+Chr(10)+Language(\MRW))
AddGadgetItem(0,-1,"Double Density CDR"+Chr(10)+Language(\DDCDR_Write))
AddGadgetItem(0,-1,"Double Density CDRW"+Chr(10)+Language(\DDCDRW_Write))
AddGadgetItem(0,-1,"Writing Modes")
SetGadgetItemColor(0, CountGadgetItems(0)-1, #PB_Gadget_FrontColor, $FF0000, 0)
AddGadgetItem(0,-1,"Raw 16"+Chr(10)+Language(\WriteModes\Raw16))
AddGadgetItem(0,-1,"Raw 16 + Test mode"+Chr(10)+Language(\WriteModes\Raw16Test))
AddGadgetItem(0,-1,"Raw 96 + Packed subchannels"+Chr(10)+Language(\WriteModes\Raw96P))
AddGadgetItem(0,-1,"Raw 96 + Packed subchannels + Test mode"+Chr(10)+Language(\WriteModes\Raw96PTest))
AddGadgetItem(0,-1,"Raw 96 + Raw subchannels"+Chr(10)+Language(\WriteModes\Raw96R))
AddGadgetItem(0,-1,"Raw 96 + Raw subchannels + Test mode"+Chr(10)+Language(\WriteModes\Raw96RTest))
AddGadgetItem(0,-1,"Session At Once (SAO)"+Chr(10)+Language(\WriteModes\SAO))
AddGadgetItem(0,-1,"SAO + test mode"+Chr(10)+Language(\WriteModes\SAOTest))
AddGadgetItem(0,-1,"SAO + Raw 96 + Packed subchannels"+Chr(10)+Language(\WriteModes\SAOR96P))
AddGadgetItem(0,-1,"SAO + Raw 96 + Packed subchannels + Test mode"+Chr(10)+Language(\WriteModes\SAOR96PTest))
AddGadgetItem(0,-1,"SAO + Raw 96 + raw subchannels"+Chr(10)+Language(\WriteModes\SAOR96R))
AddGadgetItem(0,-1,"SAO + Raw 96 + raw subchannels + Test mode"+Chr(10)+Language(\WriteModes\SAOR96RTest))
AddGadgetItem(0,-1,"Track At Once (TAO)"+Chr(10)+Language(\WriteModes\TAO))
AddGadgetItem(0,-1,"TAO + Test mode"+Chr(10)+Language(\WriteModes\TAOTest))
EndWith
AddGadgetItem(0,-1,"Other Features")
SetGadgetItemColor(0, CountGadgetItems(0)-1, #PB_Gadget_FrontColor, $FF0000, 0)
With DriveInfo\Otherfeatures
AddGadgetItem(0,-1,"Power Management"+Chr(10)+Language(\PowerManagement))
AddGadgetItem(0,-1,"Embedded Changer"+Chr(10)+Language(\EmbeddedChanger))
AddGadgetItem(0,-1,"CD Audio Analog Play"+Chr(10)+Language(\CDAudioAnalogPlay))
AddGadgetItem(0,-1,"Microcode Upgrade"+Chr(10)+Language(\MicrocodeUpgrade))
AddGadgetItem(0,-1,"Timeout"+Chr(10)+Language(\TimeOut))
AddGadgetItem(0,-1,"Real Time Streaming"+Chr(10)+Language(\RealTimeStreaming))
AddGadgetItem(0,-1,"Logical Unit Serial Number"+Chr(10)+Language(\LogicalUnitSerialNumber))
AddGadgetItem(0,-1,"Disc Control Blocks"+Chr(10)+Language(\DiscControlBlocks))
AddGadgetItem(0,-1,"DVD CSS"+Chr(10)+Language(\DVD_CSS))
AddGadgetItem(0,-1,"DVD CPRM"+Chr(10)+Language(\DVD_CPRM))
AddGadgetItem(0,-1,"Firmware Date"+Chr(10)+Language(\FirmwareDate))
AddGadgetItem(0,-1,"Analog Audio"+Chr(10)+Language(\AnalogAudio))
AddGadgetItem(0,-1,"Jitter Correction"+Chr(10)+Language(\JitterCorrection))
AddGadgetItem(0,-1,"Lock Media"+Chr(10)+Language(\LockMedia))
AddGadgetItem(0,-1,"Volume Levels"+Chr(10)+Str(\VolumeLevels))
EndWith
EndProcedure
; ================================
;- ¦¦¦¦ TEST AREA ¦¦¦¦
; ================================
CompilerIf #PB_Compiler_IsMainFile
If OpenWindow(0, 299, 243, 500, 510, "Optical Drive Info", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget)
ListIconGadget(0, 10, 30, 480, 470, "Data", 260, #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect)
AddGadgetColumn(0,2,"Value",190)
ComboBoxGadget(1,10,10,200,20)
TextGadget(2,220,12,200,18,"<-- Select a drive to view its info.")
For i=65 To 90
If GetDriveType_(Chr(i) + ":") = 5
AddGadgetItem(1,-1,Chr(i))
EndIf
Next
CurrentDrive.w; it is used to have a normal behavior from the ListIconGadget.
If CountGadgetItems(1) > 0
SetGadgetState(1,0)
ShowTheInfo(0)
EndIf
Repeat
EventID = WaitWindowEvent()
If EventID = #PB_Event_CloseWindow
Quit = 1
ElseIf EventID = #PB_Event_Gadget
If EventGadget() = 1
If GetGadgetState(1) <> CurrentDrive
CurrentDrive =GetGadgetState(1)
If CurrentDrive < 0: CurrentDrive = 0: EndIf
ShowTheInfo(CurrentDrive)
EndIf
EndIf
EndIf
Until Quit = 1
EndIf
End
CompilerEndIf