CDDA RIP by SPTI

Windows specific forum
User avatar
oryaaaaa
Addict
Addict
Posts: 832
Joined: Mon Jan 12, 2004 11:40 pm
Location: Okazaki, JAPAN

CDDA RIP by SPTI

Post by oryaaaaa »

Since there is nothing to Tips of PureBasic, I have challenged.
But, I dont know where was mistaken.
DeviceIoControl is not successful.

DeviceIoControl_( hDevice, #IOCTL_SCSI_PASS_THROUGH_DIRECT, *
ERROR 1306 "Indicates two revision levels are incompatible."

Thank you

ADD. FIX 01
no run, alliment miss?

Code: Select all

#SPT_SENSE_LENGTH = 32
#SPTWB_DATA_LENGTH = 512
#IOCTL_SCSI_PASS_THROUGH = $4D004
#SCSI_IOCTL_DATA_OUT = 0
#SCSI_IOCTL_DATA_IN	= 1
#SCSI_IOCTL_DATA_UNSPECIFIED	= 2
#IOCTL_SCSI_PASS_THROUGH_DIRECT = $4D014
#CDDASECTOR=2352
#READSECTOR=15
#SCSI_READ_TOC   = $43
#SCSIOP_READ_CD = $BE

ImportC "msvcrt.lib"
  strstr ( *lpFirst.l, *lpSrch.l )
  strlen ( *str.l )
  strchr ( *strchr.l, Char.l)
  strrchr ( *strchr.l, Char.l)
  memset_ ( *str.l, Char.l, length.l ) As "_memset@12"
EndImport

Macro REVERSE_DWORD(dword)
  (((dword>>24)&$FF)|((dword>>8)&$FF00)|((dword<<8)&$FF0000)|((dword<<24)&$FF000000))
EndMacro

Macro REVERSE_WORD(word)
  (((word>>8)&$FF)|((word<<8)&$FF00))
EndMacro

Structure TOCTRACK
  reserved.b
  CTL_ADR.b
  trackNumber.b
  Reserved2.b
  addr.b[4]
EndStructure

Structure TOC
  TOCLength.w
  firstTrack.b
  lastTrack.b
  tracks.TOCTRACK[100]
EndStructure

Structure TOCBUF
  TOCbuf.b[SizeOf(TOC)+$10]
EndStructure

Structure BYTEcmd
  byteCmd.b[16]  
EndStructure

Structure SCSI_PASS_THROUGH_DIRECT
  length.l
  ScsiStatus.b
  PathId.b
  TargetId.b
  lun.b
  CdbLength.b
  SenseInfoLength.b
  DataIn.b
  DataTransferLength.q
  TimeOutValue.q
  DataBuffer.l
  SenseInfoOffset.q
  Cdb.b[16] 
EndStructure

Structure SCSI_PASS_THROUGH_DIRECT_WITH_BUFFERS
  sptd.SCSI_PASS_THROUGH_DIRECT
  Filter.q
  ucSenseBuf.s{#SPT_SENSE_LENGTH}
EndStructure

Procedure.l ConvParagraphBoundary(*pv)
  ProcedureReturn ( (*pv+$10) & $FFFFFFF0 )
EndProcedure

Procedure.b ExecCommand( hDevice.l, *pbyteCdbCmd, byteCdbCmdLength.b , pvBuffer.l, dwBufferLength.l )
  Protected swb.SCSI_PASS_THROUGH_DIRECT_WITH_BUFFERS, ulLength.q, ulReturned.q
  memset_( @swb, 0, SizeOf(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFERS) )
  swb\sptd\length = SizeOf(SCSI_PASS_THROUGH_DIRECT)
  Debug SizeOf(SCSI_PASS_THROUGH_DIRECT)
  CopyMemory( *pbyteCdbCmd, @swb\sptd\Cdb, byteCdbCmdLength )
  swb\sptd\CdbLength = byteCdbCmdLength
  swb\sptd\SenseInfoLength = 24
  swb\sptd\DataIn = #SCSI_IOCTL_DATA_IN
  swb\sptd\DataBuffer = pvBuffer
  swb\sptd\DataTransferLength = dwBufferLength
  swb\sptd\TimeOutValue = 6  ;(sec)
  swb\sptd\SenseInfoOffset = OffsetOf(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFERS\ucSenseBuf)
  ulLength = SizeOf( SCSI_PASS_THROUGH_DIRECT_WITH_BUFFERS )
  CallDebugger
  Debug DeviceIoControl_( hDevice, #IOCTL_SCSI_PASS_THROUGH_DIRECT, @swb, ulLength, @swb, ulLength, @ulReturned, #Null)
  err = GetLastError()
  Debug GetLastErrorAsText(err)+Space(5)+Str(err)
  ProcedureReturn ulReturned
EndProcedure

Procedure.l CDReadData(cDrive.s, uTrack.b, pszOutFile.s)
  Protected hDevice.l, szBuf.s{1024}
  szBuf = "\\.\"+Left(cDrive,1)+":"
  hDevice = CreateFile_( @szBuf, #GENERIC_READ | #GENERIC_WRITE, #FILE_SHARE_READ, #Null, #OPEN_EXISTING, 0, #Null)
  If hDevice = #INVALID_HANDLE_VALUE
    ProcedureReturn #False
  EndIf
  Debug szBuf+"  ::  "+Str(hDevice)
  Protected byteTocBuffer.TOCBUF, ptoc.TOC, byteCmd.BYTEcmd
  Protected *ptoc_m = AllocateMemory(SizeOf(TOC)+$1F)
  Protected *ptoc_m1 = ConvParagraphBoundary(*ptoc_m)
  Debug *ptoc_m1
  Debug SizeOf(TOC)
  Debug SizeOf(TOC)>>8 & $FF
  Debug SizeOf(TOC) & $00FF
  PokeB(@byteCmd, #SCSI_READ_TOC)
  PokeB(@byteCmd+6, 1)
  PokeB(@byteCmd+7, SizeOf(TOC)>>8 & $FF)
  PokeB(@byteCmd+8, SizeOf(TOC) & $00FF )
  If ExecCommand( hDevice, @byteCmd, 10, *ptoc_m1, SizeOf(TOC) )=0
    Debug "EXEC FAIL"
    CloseHandle_( hDevice )
    FreeMemory(*ptoc_m)
    ProcedureReturn #False
  EndIf
  CopyMemory(*ptoc_m1, @ptoc, SizeOf(TOC))
  FreeMemory(*ptoc_m)
  If uTrack <1 Or ptoc\lastTrack < uTrack
    Debug "Faul"
    CloseHandle_( hDevice )
    ProcedureReturn #False
  EndIf
  If ( ptoc\tracks[uTrack-1]\CTL_ADR And $04 )
    CloseHandle_( hDevice ) ; Data-Track
    ProcedureReturn #False
  EndIf
  Protected fp.l = CreateFile(#PB_Any, pszOutFile )
  If fp=0
    CloseHandle_( hDevice )
    ProcedureReturn #False
  EndIf
  Protected dwStartAddress.l = REVERSE_DWORD( ptoc\tracks[uTrack-1]\addr )
  Protected dwEndAddress.l = REVERSE_DWORD( ptoc\tracks[uTrack]\addr ) - 1
  Protected dwLength.l = REVERSE_DWORD( ptoc\tracks[uTrack]\addr) -REVERSE_DWORD(ptoc\tracks[uTrack-1]\addr)
  
	; printf( "Track %u, LBA %6u-%6u, Length %6u\n", uTrack, dwStartAddress, dwEndAddress, dwLength );

  Protected *byteBuffer = AllocateMemory( #CDDASECTOR*#READSECTOR +$10 )
  Protected *pbyteBuf
  memset_( *byteBuffer, 0, SizeOf(*byteBuffer))
	; pbyteBuf = (BYTE*)ConvParagraphBoundary(byteBuffer);
  memset_( @byteCmd, 0, SizeOf(BYTEcmd) )
  PokeB( @byteCmd,  #SCSIOP_READ_CD )
  PokeB( @byteCmd+7,  #READSECTOR )
  PokeB( @byteCmd+8, $10 )
  Protected dwLBA.l
  For dwLBA=dwStartAddress To dwEndAddress
    Protected dwReadSize.l
    If (dwLBA+#READSECTOR) > dwEndAddress
      dwReadSize = dwEndAddress - dwLBA
    Else
      dwReadSize = #READSECTOR
    EndIf
    PokeL( @byteCmd+2, REVERSE_DWORD(dwLBA) )
    PokeB( @byteCmd+8, dwReadSize )
    
    If ExecCommand( hDevice, byteCmd, 12, *pbyteBuf,  #CDDASECTOR*#READSECTOR)
      CloseHandle_( hDevice )
      ProcedureReturn #False
    EndIf
    
    WriteData(fp, *pbyteBuf, dwReadSize * #CDDASECTOR)
    dwLBA + dwReadSize
		; printf( "\r%6u/%6u", dwLBA, dwEndAddress ); 
  Next
  CloseFile(fp)
  CloseHandle_( hDevice )
  ProcedureReturn #True
EndProcedure

CDReadData(PathRequester("CD DRIVE","\"), 0, "testdata")

End
User avatar
oryaaaaa
Addict
Addict
Posts: 832
Joined: Mon Jan 12, 2004 11:40 pm
Location: Okazaki, JAPAN

Post by oryaaaaa »

1306 error, The error which is wrong in usage

SPTI DDK part. 7zip
http://oryaaaaa.world.coocan.jp/kakakupic/spti.7z

I do my best for a while. :(
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: CDDA RIP by SPTI

Post by doctorized »

Sorry for replaying to this old post but I want to ask if you found the solution to your problem.
First of all, the structure should be like this:

Code: Select all

Structure SCSI_PASS_THROUGH_DIRECT
  length.w
  ScsiStatus.b
  PathId.b
  TargetId.b
  lun.b
  CdbLength.b
  SenseInfoLength.b
  DataIn.b
  padding0.b[3]
  DataTransferLength.l
  TimeOutValue.i
  DataBuffer.i
  SenseInfoOffset.i
  Cdb.b[16]
EndStructure
In older x86 PB you should have .l and not .q variables. Now, for x64 compatibility we need .i but DataTransferLength must remain .l to get rid of error 1306. Now, at least to me, DeviceIOControl returns no data and GetLastError_() says that operation completed successfully.
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: CDDA RIP by SPTI

Post by doctorized »

I solved the problem with DeviceIOControl and x64 executable. See this: http://purebasic.fr/english/viewtopic.php?f=40&t=57709
Post Reply