Projekte > Optische Laufwerke > Laufwerke

Bezeichnungen

Mit der Funktion CreateFile erhält man ein Handle auf das Laufwerk. Dazu kann das Laufwerk mit dem Device Namespace oder dem File Namespace angegeben werden. Anschließend greift man sich mit der Funktion DeviceIOControl und dem ControlCode IOCTL_SCSI_PASS_THROUGH_DIRECT auf das SCSI Pass Through Interface zu erhält mit dem INQUIRY Command die Bezeichnung des Laufwerkes. Nähere Informationen zu dem Multi Media Command gibt es unter ..................

Deklarationen:

 
  const
    SCSIOP_INQUIRY = $12;

  type
    TSCSI_INQUIRY_CDB = record
      OperationCode    : Byte;
      EVPD             : Byte;
      PageCode         : Byte;
      AllocationLength : Word;
      Control          : Byte;
    end;

  type
    TINQUIRY_STANDARD_DATA = record
      Other_Informations_1    : Array[0..7] of Byte;
      T10VendorIdentification : array[0..7] of Char;
      ProductIdentification   : array[0..15] of Char;
      ProductRevisionLevel    : array[0..3] of Char;
      VendorSpecific0         : array[0..19] of Char;
      Other_Informations_2    : Array[0..43] of Byte;
    end;
                

Die im Moment nicht benötigten Informationen werden hier mit Other_Informations_1 und Other_Information_2 bezeichnet.

Die Ausführung könnte beispielsweise so aussehen:

 
  function TOptDrives.ReadInquiry(aDevice: THandle): Boolean;
  {*******************************************************************************
  *  Inquiry Command
  }
  var
    SCSI_INQUIRY_CDB : TSCSI_INQUIRY_CDB;
    pInquiryData     : pINQUIRY_STANDARD_DATA;
    aCDB             : Array of Byte;
    i                : Integer;
  begin
    {
    *  Das übergebene Handle auf Gültigkeit prüfen.
    }
    if aDevice <> INVALID_HANDLE_VALUE
    then begin
      {
      *  Den Command Descriptor Block füllen.
      }
      ZeroMemory(@SCSI_INQUIRY_CDB, SizeOf(SCSI_INQUIRY_CDB));
      SCSI_INQUIRY_CDB.OperationCode    := SCSIOP_INQUIRY;
      SCSI_INQUIRY_CDB.AllocationLength := SizeOf(TINQUIRY_STANDARD_DATA);
      {
      *  Den Command Descriptor Block übertragen.
      }
      SetLength(aCDB, 6);
      aCDB[0] := SCSI_INQUIRY_CDB.OperationCode;
      aCDB[1] := SCSI_INQUIRY_CDB.EVPD;
      aCDB[2] := SCSI_INQUIRY_CDB.PageCode;
      aCDB[3] := HiByte(SCSI_INQUIRY_CDB.AllocationLength);
      aCDB[4] := LoByte(SCSI_INQUIRY_CDB.AllocationLength);
      aCDB[5] := SCSI_INQUIRY_CDB.Control;
      {
      *  Befehl ausführen. Manchmal ist es notwendig, den Speicher anzufordern.
      }
      GetMem(pInquiryData, SizeOf(TINQUIRY_STANDARD_DATA));
      Result := GET_SCSI_PASS_THROUGH_DIRECT(aDevice, aCDB,
                                             pInquiryData,
                                             SizeOf(TINQUIRY_STANDARD_DATA));
      if Result then
      with fDrive[fActive].DeviceInfo
      do begin
        T10VendorIdentification := Trim(pInquiryData.T10VendorIdentification);
        ProductIdentification   := Trim(pInquiryData.ProductIdentification);
        ProductRevisionLevel    := Trim(pInquiryData.ProductRevisionLevel);
        VendorSpecific0         := Trim(pInquiryData.VendorSpecific0);
      end;
      FreeMem(pInquiryData);
    end;
  end;
          

Informationen zur Funktion GET_SCSI_PASS_THROUGH_DIRECT gibt es in Anhang 1. In der Demo wird die Funktion ReadInquiry bei der Erstellung der Klasse aufgerufen.

 
  constructor TOptDrives.Create;
  {*******************************************************************************
  *  Class erstellen.
  }
  var
    i       : Integer;
    hDevice : THandle;
  begin
    {
    *  Laufwerksbuchstaben ermitteln.
    }
    if ReadDrives > 0
    then begin
      for i := 0 to Length(fDrive) - 1
      do begin
        fActive := i;
        hDevice := DriveHandle(fDrive[fActive].Letter);
        if hDevice <> INVALID_HANDLE_VALUE
        then begin
          ReadSCSIAddress(hDevice);
          ReadInquiry(hDevice);
          CloseHandle(hDevice);
        end;
      end;
    end;
  end;
          

Das Ergebnis des Beispiels sieht so aus:

Description (podDescription.7z - 230 kb) MD5 (1 kb). Stand: 28. April 2013

Änderungen an der Demo

Datum Beschreibung
28.04.2013Kleine Überarbeitung und neuer Name.
04.04.2013Überarbeitung.