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 - Hardware - Mechanismus

Mechanismus

MECHANISM STATUS Command - Operation Code $BD

Multi-Media Commands - 6 Kapitel 6.10. Das MECHANISM STATUS Command ruft den gegenwärtigen Status des Mechanismus, einschließlich der Wechslermechanismen, welche den Standard unterstützen, ab. Der Befehl wurde bereits im Kapitel Mechanik - Status der Schublade benutzt.

Der MECHANISM STATUS Command Descriptor Block:

 76543210
0Operation Code ($BD)
1Reserviert
2
3
4
5
6
7
8Allocation Length
9
10Reserviert
11Control

Die Werte:

Byte 0: Operation Code = $BD

Byte 8 und 9: Länge der Antwortstruktur = SizeOf(TMechanismStatusHeader) = $20

Byte 11: Control - ?

Die Antwortstruktur:

Auf acht Byte Mechanism Status Header folgen die Slot tables. Hier der Techanism Status Header:

 76543210
0FaultChanger StateCurrent Slot (Low order))
1Mechanism StateDoor OpenReserviertCurrent Slot (High order)
2Current LBA (Legacy)
3
4
5Number of Slots Available
6Length of Slot Tables
7

Fault
Gibt an, ob die Ausführung der Aktion, welche im Changer State angegeben ist, scheiterte.

Changer State

Changer StateDefinition
$0Ready
$1Load in Progress
$2Unload in Progress
$3Initialisierung

Current Slot
Gibt den aktuell ausgewählten Slot an. Bei Geräten, welche bootfähig sind, sollte dies nach der Initialisierung der Slot 0 sein. Wenn das Gerät kein Wechsler ist, ist das Feld reserviert.

Mechanism State

Mechanism StateDefinition
$0Idle
$1Legacy definition - Playing (Audio or Data)
$2Legacy definition - Scanning
$3Legacy definition - Active with Host, Composite or Other Ports in use (zB READ)
$4 - $6Reserviert
$7No State Information Available

Door open
Wenn das Bit gesetzt ist, ist die Tür/Schublade offen oder das Magazin nicht eingesetzt.

Current LBA
LBA (Logical Block Addressing) gibt den Sektor an, von welchem zuletzt gelesen wurde.

Number of Slots
Anzahl der verfügbaren Slots. Wenn das Gerät kein Wechsler ist, ist der Wert 0.

Length of Slot Tables
Gibt die Anzahl der Bytes an, welche mit Slot Informationen belegt sind. Sie berägt ein Vielfaches von vier.

Eine Slot Table:

 76543210
0Disc PresentReservedChange
1ReservedCWP_VCWP
2Reserved
3

Disc Present
Gibt an, ob eine Disc eingelegt ist.

Change
Gibt an, ob die Disc seit den letzten Laden geändert wurde. Das Flag ist obligatorisch.

CWP_V
Gibt an, das die Media Cartridge Write Protection in diesem Slot geprüft wurde und das Flag CWP gültig ist.

CWP
Gibt an, ob die Media Cartridge Write Protection für den Slot aktiv ist.

Deklaratioen

Für die Ausführung:

const
  SCSIOP_MECHANISM_STATUS = $BD;
 
type
  TMECHANISM_STATUS_CDB = record
    OperationCode    : Byte;
    AllocationLength : Word;
    Control          : Byte;
  end;
 
type
  TMECHANISM_STATUS_PARAMETER_LIST = record
    MechanismStatusHeader : Array[0..7] of Byte;
    SlotTable             : Array[0..39] of Byte;
  end;
  PMECHANISM_STATUS_PARAMETER_LIST = ^TMECHANISM_STATUS_PARAMETER_LIST;

Für die Auswertung:

type
  TMechanismStatusHeader = record
    Fault                  : Boolean;
    ChangerState           : Byte;
    CurrentSlot            : Byte;
    MechanismState         : Byte;
    DoorOpen               : Boolean;
    CurrentLBA             : Array[0..2] of Byte;
    NumberOfSlotsAvailable : Byte;
    LengthOfSlotTables     : Word;
  end;
 
type
  TSlotTable = record
    DiscPresent : Boolean;
    Change      : Boolean;
    CWP_V       : Boolean;
    CWP         : Boolean;
  end;
 
type
  TMechanismStatusParameterList = record
    MechanismStatusHeader : TMechanismStatusHeader;
    SlotTables            : Array of TSlotTable;
  end;

Ausführung und Auswertung

Der Command Descriptor Comman wird ausgefüllt, der Befehl ausgeführt und anschließend die Antwortstruktur ausgewertet.

function TOptDrives.ReadMechanismStatus(aDevice: THandle): Boolean;
{*******************************************************************************
*  Den Status des Mechanismus ermitteln.
}
var
  MECHANISM_STATUS_CDB : TMECHANISM_STATUS_CDB;
  pMechanismStatus     : PMECHANISM_STATUS_PARAMETER_LIST;
  aCDB                 : Array of Byte;
  i                    : Integer;
begin
  Result := False;
  {
  *  Mechanismus Status initialisieren.
  }
  FillChar(FDrive[FActive].MechanismStatus,
           SizeOf(FDrive[FActive].MechanismStatus), $00);
  {
  *  Den Command Descriptor Block füllen.
  }
  ZeroMemory(@MECHANISM_STATUS_CDB, SizeOf(MECHANISM_STATUS_CDB));
  MECHANISM_STATUS_CDB.OperationCode    := SCSIOP_MECHANISM_STATUS;
  MECHANISM_STATUS_CDB.AllocationLength := SizeOf(TMECHANISM_STATUS_PARAMETER_LIST);
  {
  *  Den Command Descriptor Block übertragen.
  }
  SetLength(aCDB, 12);
  aCDB[0]  := MECHANISM_STATUS_CDB.OperationCode;
  aCDB[8]  := HiByte(MECHANISM_STATUS_CDB.AllocationLength);
  aCDB[9]  := LoByte(MECHANISM_STATUS_CDB.AllocationLength);
  {
  *  Befehl ausführen
  }
  GetMem(pMechanismStatus, SizeOf(TMECHANISM_STATUS_PARAMETER_LIST));
  if GET_SCSI_PASS_THROUGH_DIRECT(aDevice, aCDB, pMechanismStatus,
                                  SizeOf(TMECHANISM_STATUS_PARAMETER_LIST)) then
  with FDrive[FActive].MechanismStatus.MechanismStatusHeader
  do begin
    {
    *  Header lesen
    }
    Fault                  := pMechanismStatus.Header[0] and $80 > 0;
    ChangerState           := pMechanismStatus.Header[0] and $60 shr 5;
    CurrentSlot            := pMechanismStatus.Header[0] and $15 or
                              pMechanismStatus.Header[1] and $07 shl 5;
    MechanismState         := pMechanismStatus.Header[1] shr 6;
    DoorOpen               := pMechanismStatus.Header[1] and $10 > 0;
    CurrentLBA[0]          := pMechanismStatus.Header[2];
    CurrentLBA[1]          := pMechanismStatus.Header[3];
    CurrentLBA[2]          := pMechanismStatus.Header[4];
    NumberOfSlotsAvailable := pMechanismStatus.Header[5];
    LengthOfSlotTables     := pMechanismStatus.Header[6] shl 8 or
                              pMechanismStatus.Header[7];
    {
    *  Wenn es ein Wechsler ist und es Slots gibt.
    }
    if NumberOfSlotsAvailable > 0
    then begin
      SetLength(FDrive[FActive].MechanismStatus.SlotTables, NumberOfSlotsAvailable);
      for i := 0 to NumberOfSlotsAvailable - 1 do
      with FDrive[FActive].MechanismStatus.SlotTables[i]
      do begin
        DiscPresent := pMechanismStatus.SlotTable[i * 4 + 0] and $80 > 0;
        Change      := pMechanismStatus.SlotTable[i * 4 + 0] and $01 > 0;
        CWP_V       := pMechanismStatus.SlotTable[i * 4 + 1] and $02 > 0;
        CWP         := pMechanismStatus.SlotTable[i * 4 + 1] and $01 > 0;
      end;
    end;
    {
    *  Ergebnis
    }
    Result := True;
  end;
end;

CD-Wechsler dürften in PCs selten sein. Somit dürften eigentlich nur die Informationen Door_Open und eventuell CurrentLBA, welcher sich bei jedem Dateizugriff ändert, interessant sein.

Demo, welche diese Funktion nutzt:

MechanismscStatus (podMechanism.7z - 305 kb) MD5 (1 kb). Stand: 30. Juni 2013

DVD Region > Mechanism Status > Hardware