Projekte > Optische Laufwerke > Merkmale

Profile List

GET CONFIGURATION Command - Operation Code $46
PROFILE LIST FEATURE - Feature Number $0000

Im Kapitel Feature wurde die Feature List ermittelt. Das Profile List Feature ist in den Multimedia Commands 6 in Kapitel 5.3.1 beschreiben. Wenn das Feature unterstützt wird, kann man dieses abrufen. Dazu wird dieser Command Descriptor Block verwendet:

  7 6 5 4 3 2 1 0
0 Operation Code = $46
1 Reserviert RT = 10b
2 Starting Feature Number = $0000
3
4 Reserviert
5
6
7 Allocation Length = $00A4
8
9 Control

 

Die Werte:

Byte 0 Operation Code - $46 GET CONFIGURATION Command

Byte 1 Request Type (RT) - 10b Feature Header, auch wenn das Feature nicht unterstützt wird.

Wert Beschreibung
00b Das Laufwerk soll den Feature Header und alle durch das Laufwerk unterstützten Feature Beschreibungen zurückgeben ohne Rücksicht auf Geltung.
01b Das Laufwerk soll den Feature Header und nur die gewählte Feature Beschreibung zurückgeben.
10b Das Laufwerk soll den Feature Header und nur die gewählte Feature Beschreibung zurückgeben. Wird das Feature nicht unterstützt, soll nur der Feature Header zurückgegeben werden.
11b Reserviert

 
Byte 2 und 3 Starting Feature Number - $0000: Die Nummer des Profile List Feature, welches ausgegeben werden soll.

Byte 7 und 8 Allocation Length - $00AC: Länge der Antwortstruktur. Sie muss so gewählt werden, dass die erwartete Antwort hineinpasst. Der Feature Header hat eine Länge von acht Byte. Es folgt die Profile List Feature Beschreibung mit vier Byte sowie die Profilbeschreibungen (Liste der Profile in einem Fenster öffnen.) mit jeweils vier Byte. Mit etwas Reserve ist eine Länge von $00AC ausreichend.

Byte 9: Control - ?
 

Antwortstruktur

Die Antwort besteht wie oben erwähnt aus dem Feature Header:

  7 6 5 4 3 2 1 0
0 Data Length
1
2
3
4 Reserviert
5
6 Current Profile
7

 
Data Length - Die Datenlänge gibt in Bytes an, wieviele Daten diesem Feld folgen. Der Wert ist ein Vielfaches von vier.

Current Profile - Gibt das aktive Profil an. Das Profil ist vom Laufwerk und dem eingelegten Datenträger abhängig. Sind mehrere Profile aktiv wird das Profil mit der höchsten Nummer angegeben. (Liste der Profile in einem Fenster öffnen.)

Darauf folgt die Profile List Feature Beschreibung mit den Profilbeschreibungen:

  7 6 5 4 3 2 1 0
0 Feature Code = $0000
1
2 Reserviert Version Persistent Current
3 Additional Length
4..n Profile Descriptor(s)

 
Feature Code - Muss der selbe wie im CDB sein. Hier war das Profile List Feature $0000 ausgewählt.

Version - Die Versionsnummer muss 0000b sein.

Persistent - Gibt an, ob das Profile List Feature immer unterstützt wird.

Current - Muss auf 1b gesetzt sein.

Additional Length - Der Wert muss ein vielfaches von vier betragen, weil ein Profile Descriptor vier Byte lang ist.

Profile Descriptor(s) (Profilbeschreibungen):

  7 6 5 4 3 2 1 0
0 Profile Number
1
2 Reserviert Current
3 Reserviert

 
Profile Number - Die Werte entsprechen denen bei Current Profile.

Current - Gibt an, ob das Profile gerade aktiv ist.
 

Deklarationen

Zusätzlich zu den Deklarationen im Kapitel Feature werden diese vorgenommen:

 
  type
    TGET_CONFIGURATION_PROFILE_LIST = record
      Header : Array[0..$07] of Byte;
      Data   : Array[0..$A3] of Byte;
    end;
    PGET_CONFIGURATION_PROFILE_LIST = ^TGET_CONFIGURATION_PROFILE_LIST;
 
  type
    TGetConfigurationHeader = record
      DataLength     : Cardinal;
      CurrentProfile : Word;
    end;
 
    TProfile = record
      Number  : Word;
      Current : Boolean;
    end;
 
    TFeatureProfile = record
      FeatureCode : Word;
      Version     : Byte;
      Persistent  : Boolean;
      Current     : Boolean;
      AddLength   : Byte;
      ProfileList : Array of TProfile;
    end;
        

 

Ausführung

Beispielfunktion: Nach dem Füllen des Command Descriptur Blocks wird er in ein Array übertragen. Anschließend 7 wird der Befehl ausgeführt und ausgewertet.

 
  function TOptDrives.ReadConfigProfileList(aDevice: THandle): Boolean;
  {*******************************************************************************
  *  GET CONFIGURATION Profile List Feature
  }
  var
    GET_CONF_CDB  : TGET_CONFIGURATION_CDB;
    pConfProfList : PGET_CONFIGURATION_PROFILE_LIST;
    aCDB          : Array of Byte;
    i, n          : Integer;
    DataLength    : Cardinal;
  begin
    {
    *  Profile List initialisieren.
    }
    FillChar(FDrive[FActive].ProfileList, SizeOf(TFeatureProfile), $00);
    {
    *  Den Command Descriptor Block füllen.
    }
    ZeroMemory(@GET_CONF_CDB, SizeOf(TGET_CONFIGURATION_CDB));
    GET_CONF_CDB.OperationCode         := SCSIOP_GET_CONFIGURATION;
    GET_CONF_CDB.RequestType           := RT_Identified;
    GET_CONF_CDB.StartingFeatureNumber := FEATURE_PROFILE_LIST;
    GET_CONF_CDB.AllocationLength      := SizeOf(TGET_CONFIGURATION_PROFILE_LIST);
    {
    *  Den Command Descriptor Block übertragen.
    }
    SetLength(aCDB, CDB10GENERIC_LENGTH);
    aCDB[0] := GET_CONF_CDB.OperationCode;
    aCDB[1] := GET_CONF_CDB.RequestType;
    aCDB[2] := HiByte(GET_CONF_CDB.StartingFeatureNumber);
    aCDB[3] := LoByte(GET_CONF_CDB.StartingFeatureNumber);
    aCDB[7] := HiByte(GET_CONF_CDB.AllocationLength);
    aCDB[8] := LoByte(GET_CONF_CDB.AllocationLength);
    {
    *  Befehl ausführen
    }
    GetMem(pConfProfList, SizeOf(TGET_CONFIGURATION_PROFILE_LIST));
    Result := GET_SCSI_PASS_THROUGH_DIRECT(aDevice, aCDB, pConfProfList,
                                           SizeOf(TGET_CONFIGURATION_PROFILE_LIST));
    if Result
    then begin
      DataLength := pConfProfList.Header[0] shl 24 or
                    pConfProfList.Header[1] shl 16 or
                    pConfProfList.Header[2] shl  8 or
                    pConfProfList.Header[3];
      {
      *  Wenn das PROFILE LIST Feature existiert.
      }
      if DataLength > 4 then
      with FDrive[FActive].ProfileList
      do begin
        FeatureCode := pConfProfList.Data[0] shl 8 or pConfProfList.Data[1];
        Version     := pConfProfList.Data[2] and $3C shr 2;
        Persistent  := pConfProfList.Data[2] and $02 > 0;
        Current     := pConfProfList.Data[2] and $01 > 0;
        AddLength   := pConfProfList.Data[3];
        {
        *  Wenn Daten vorhanden sind diese übernehmen.
        }
        if AddLength > 0
        then begin
          n := AddLength div 4;
          SetLength(Profile, n);
          for i := 0 to n - 1
          do begin
            Profile[i].Number  := pConfProfList.Data[4 + (i * 4)] shl 8 or
                                  pConfProfList.Data[5 + (i * 4)];
            Profile[i].Current := pConfProfList.Data[6 + (i * 4)] and $01 > 0;
          end;
        end;
        {
        *  Ergebnis
        }
        Result := FeatureCode = FEATURE_PROFILE_LIST;
      end;
    end;
  end;
          

Anmerkung: In der Funktion wird with ... do nicht verwendet.

Demo, welche diese Funktion nutzt:

Profile List (podProfileList.7z - 250 kb) MD5 (1 kb). Stand: 2. Juni 2013

Änderungen an der Demo

Datum Beschreibung
02.06.2013Kleine Überarbeitung und neuer Name.
27.01.2012Fehler: Beim Speichern war eine Änderung nicht übernommen worden.