Projekte > Optische Laufwerke > Anhang

GET_SCSI_PASS_THROUGH_DIRECT

Um Multi Media Commands über das SCSI Pass Through Interface auszuführen wird in den Demos die Funktion GET_SCSI_PASS_THROUGH_DIRECT verwendet. Diese Funktion ist Bestandteil der Delphi-Class, welche im Zusammenhang mit diesem Projekt entstanden ist.

 
  function GET_SCSI_PASS_THROUGH_DIRECT(
   hDevice: THandle;
   aCDB: Array of Byte;
   pDataBuffer: Pointer;
   nDataBufferSize: Cardinal
   ): boolean;
          

 

Parameter

hDevice: THandle; [in]
Das Handle auf das Laufwerk, auf welchem der Befehl ausgeführt werden soll.

 

aCDB: Array of Byte; [in]
Der Command Descriptor Block, welcher das Multi Media Command sowie dessen Einstellungen enthält und in die Struktur TSCSI_PASS_THROUGH_DIRECT eingetragen wird um in der Funktion DeviceIoControl verwendet zu werden. In Abhängigkeit vom Multi Media Command ist der Command Descriptor Block sechs, zehn oder zwölf Byte lang. Maximal darf er 16 Byte lang sein.

 
  type
    TSCSI_PASS_THROUGH_DIRECT = record
      Length              : Word;
      ScsiStatus          : Byte;
      PathId              : Byte;
      TargetId            : Byte;
      Lun                 : Byte;
      CdbLength           : Byte;
      SenseInfoLength     : Byte;
      DataIn              : Byte;
      DataTransferLength  : Cardinal;
      TimeOutValue        : Cardinal;
      DataBufferOffset    : Pointer;
      SenseInfoOffset     : Cardinal;
      Cdb                 : Array[0..15] of Byte;
    end;
    PSCSI_PASS_THROUGH_DIRECT = ^TSCSI_PASS_THROUGH_DIRECT;
          

pDataBuffer: Pointer; [in]
Der Pointer auf den reservierten Speicherbereich, in welchen die Antwortstruktur geschrieben werden soll. Die Antwortstruktur ist vom verwendeten Multi Media Command abhängig.

 

nDataBufferSize: Cardinal [in]
Die Größe des für die Antwortstruktur reservierten Speichers in Byte;

 

Rückgabewert

Die Funktion gibt True zurück wenn die Funktion DeviceIoControl erfolgreich ausgeführt werden konnte.

 

Der Quelltext der Funktion

 
  function GET_SCSI_PASS_THROUGH_DIRECT(hDevice: THandle; aCDB: Array of Byte;
             pDataBuffer: Pointer; nDataBufferSize: Cardinal): boolean;
  {*******************************************************************************
  *  Den Befehl mit SCSI_PASS_THROUGH_DIRECT ausführen.
  }
  var
    i              : Byte;
    pSPTD          : PSCSI_PASS_THROUGH_DIRECT;
    buffer         : array[0..1023] of AnsiChar;
    nInBufferSize  : Cardinal;
    nOutBufferSize : Cardinal;
    nReturned      : Cardinal;
  begin
    Result := False;
    {
    *  Wenn das Handle gültig ist.
    }
    if hDevice <> INVALID_HANDLE_VALUE
    then begin
      {
      *  Buffer initialisieren und Datenstruktur füllen
      }
      ZeroMemory(pDataBuffer, nDataBufferSize);
      ZeroMemory(@buffer, Length(buffer));
      pSPTD                     := PSCSI_PASS_THROUGH_DIRECT(@buffer);
      pSPTD^.Length             := SizeOf(TSCSI_PASS_THROUGH_DIRECT);
      pSPTD^.CdbLength          := Length(aCDB);
      pSPTD^.SenseInfoLength    := 0;
      pSPTD^.SenseInfoOffset    := SizeOf(TSCSI_PASS_THROUGH_DIRECT);
      pSPTD^.DataIn             := SCSI_IOCTL_DATA_IN;
      pSPTD^.DataTransferLength := nDataBufferSize;
      pSPTD^.TimeOutValue       := 5;
      pSPTD^.DataBufferOffset   := pDataBuffer;
      pSPTD^.SenseInfoOffset    := SizeOf(pSPTD^);
      {
      *  CDB übertragen. Mit einer Schleife, weil das Ziel eine feste und die
      *  Quelle eine dynamische Länge besitzt.
      }
      for i := 0 to Length(aCDB) - 1
      do pSPTD^.cdb[i] := aCDB[i];
      {
      *  Anfrage stellen.
      }
      nInBufferSize  := SizeOf(TSCSI_PASS_THROUGH_DIRECT);
      nOutBufferSize := SizeOf(TSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER);
      Result := DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT,
                                pSPTD, nInBufferSize, pSPTD, nOutBufferSize,
                                nReturned, nil);
    end;
  end;
          

Für manche Anfragen ist es notwendig, dass der Wert für SenseInfoLength ungleich 0 ist. Zum Beispiel beim READ DISC INFORMATION Command wenn man die Daemon Tools Laufwerke abfragt. Im Internet findet man als Werte 14 und 24.