Home | Kontakt | Sitemap

Start

Über mich

Kontakt

Sitemap

Lizenz

Anleitungen

DVD, miniDVD

SVCD

Audio, Audio-CD (CD-DA)

AVI

Software

Von Freunden und Bekannten

Eigene Programme

Programmierung

Delphi

Lazarus

Delphi/Lazarus

Projekte

MPEG-1/2 Video

Optische Laufwerke

Audio-CD (CDDA)

Raspberry Pi Dashcam

Verschiedenes

MPEG 2 Schnitt

Project X

VCD Easy

Hardlinks

Windows

Links

Software

Projekte | Optische Laufwerke - Anhang - GET_SCSI_PASS_THROUGH_DIRECT

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.

DriveHandleRead > GET_SCSI_PASS_THROUGH_DIRECT > Anhang