Detailed information about optical drives

Windows specific forum
Little John
Addict
Addict
Posts: 4519
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Detailed information about optical drives

Post by Little John »

Hi,

I want to get detailed information about the optical drive(s) in or connected to a computer (on Windows).
As far as I can see, this is only possible by calling IMAPI functions.

Maybe in PureBasic COMAte plus can be used to do so. Anyway, I have no idea how to do it.
For instance, I would like to run the following VB example code. Perhaps someone can translate it to PureBasic?

https://docs.microsoft.com/de-de/window ... ve-support

Code: Select all

' This script examines the burn device characteristics such as 
' product ID, product revision level, feature set, and profiles. 

' Copyright (C) Microsoft Corp. 2006

Option Explicit

' Constants
const IMAPI_FEATURE_PAGE_TYPE_DVD_DASH_WRITE = 47

WScript.Quit(Main)

Function Main
    Dim Index                ' Index to recording drive.
    Dim Recorder             ' Recorder object
    Dim Path                 ' Directory of files to burn
    Dim Stream               ' Data stream for burning device
    
    Index = 1                ' Second drive on the system

    ' Create a DiscMaster2 object to connect to CD/DVD drives.
    Dim g_DiscMaster
    Set g_DiscMaster = WScript.CreateObject("IMAPI2.MsftDiscMaster2")

    ' Create a DiscRecorder object for the specified burning device.
    Dim uniqueId
    set recorder = WScript.CreateObject("IMAPI2.MsftDiscRecorder2")
    uniqueId = g_DiscMaster.Item(Index)
    recorder.InitializeDiscRecorder( uniqueId )

    ' *** - Formatting to display recorder info
    WScript.Echo "--------------------------------------------------"
    Wscript.Echo " ActiveRecorderId: " & recorder.ActiveDiscRecorder
    Wscript.Echo "        Vendor Id: " & recorder.VendorId
    Wscript.Echo "       Product Id: " & recorder.ProductId
    Wscript.Echo " Product Revision: " & recorder.ProductRevision
    Wscript.Echo "       VolumeName: " & recorder.VolumeName
    Wscript.Echo "   Can Load Media: " & recorder.DeviceCanLoadMedia
    Wscript.Echo "    Device Number: " & recorder.LegacyDeviceNumber

    Dim mountPoint
    For Each mountPoint In recorder.VolumePathNames
        WScript.Echo "      Mount Point: " & mountPoint
    Next

    WScript.Echo "Supported Features"  'in _IMAPI_FEATURE_PAGE_TYPE 
    Dim supportedFeature
    For Each supportedFeature  in recorder.SupportedFeaturePages
        if supportedFeature = _
            IMAPI_FEATURE_PAGE_TYPE_DVD_DASH_WRITE then
                WScript.Echo "    Feature: " & supportedFeature & _
                    "  Drive supports DVD-RW."
        else
                     WScript.Echo "    Feature: " & supportedFeature
        end if
    Next
    
    WScript.Echo "Current Features"    'in _IMAPI_FEATURE_PAGE_TYPE
    Dim currentFeature
    For Each currentFeature  in recorder.CurrentFeaturePages
        WScript.Echo "    Feature: " & currentFeature
    Next
    
    WScript.Echo "Supported Profiles"  'in _IMAPI_PROFILE_TYPE
    Dim supportedProfile
    For Each supportedProfile  in recorder.SupportedProfiles
        WScript.Echo "    Profile: " & supportedProfile
    Next

    WScript.Echo "Current Profiles"    'in _IMAPI_PROFILE_TYPE
    Dim currentProfile
    For Each currentProfile    in recorder.CurrentProfiles
        WScript.Echo "    Profile: " & currentProfile
    Next
    
    WScript.Echo "Supported Mode Pages"  'in  _IMAPI_MODE_PAGE_TYPE
    Dim supportedModePage       
    For Each supportedModePage in recorder.SupportedModePages
        WScript.Echo "    Mode Page: " & supportedModePage
    Next

    WScript.Echo
    WScript.Echo "----- Finished content -----"
    Main = 0
End Function
Thanks in advance for any help.
Last edited by Little John on Fri Apr 26, 2019 3:20 pm, edited 1 time in total.
User avatar
blueb
Addict
Addict
Posts: 1041
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

Re: Calling IMAPI functions with PureBasic

Post by blueb »

Hi Little John,

I found the following code on my hard drive from 2010!
But I can't determine from where.

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
- It was too lonely at the top.

System : PB 6.10 Beta 9 (x64) and Win Pro 11 (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
Little John
Addict
Addict
Posts: 4519
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Detailed information about optical drives

Post by Little John »

blueb wrote:Hi Little John,

I found the following code on my hard drive from 2010!
But I can't determine from where.
Hi blueb,

that's pretty cool. 8) Thank you sooooo much :!:
blueb wrote:It's not IMAPI but it may help you. :)
Not IMAPI? That's even better! :D
I was under the (now proven wrong) impression that something like this would on Windows only be possible with IMAPI. And accordingly, I also chose a bad thread title (now changed).

The code seems to work well with PB 32 bit (tested with version 5.62), it detects my DVD writer and my Blu-ray writer.
However, it does not work (here) with PB 64 bit (tested also with version 5.62). But I'm confident that I can make it run on 64 bit, too. For instance, the code contains several Long variables that probably should be changed to Integer.

When I have some time, now I have the chance to add serious and precise detection and description of optical drives to my BSI program.
I am very grateful for that. Thanks again :!:
User avatar
blueb
Addict
Addict
Posts: 1041
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

Re: Detailed information about optical drives

Post by blueb »

I am very grateful for that. Thanks again
No problem.. I'm sure many users will find it useful. :)
- It was too lonely at the top.

System : PB 6.10 Beta 9 (x64) and Win Pro 11 (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
Post Reply