Projekte > Optische Laufwerke > Laufwerke

SCSI-Adressen

Mit der Funktion DeviceIOControl und dem ControlCode IOCTL_SCSI_GET_ADDRESS lässt sich die SCSI-Adresse eines Laufwerkes ermitteln. Dazu muss mit CreateFile das Handle auf das jeweilige Laufwerk geholt werden. Dazu kann man wie unter Counter den Device Namespace oder unter Verwendung der ermittelten Buchstaben den File Namespaces verwenden.

Deklaration für die SCSI-Adressen

 
  type
    TSCSI_ADDRESS = record
      Length     : LongInt;
      PortNumber : Byte;
      PathId     : Byte;
      TargetId   : Byte;
      Lun        : Byte;
    end;
    PSCSI_ADDRESS = ^TSCSI_ADDRESS;
        

Die Ermittlung der SCSI-Adressen erfolgt in einer Funktion:

 
  function TOptDrives.ReadSCSIAddress(aDevice: THandle): Boolean;
  {*******************************************************************************
  *  Die SCSI Adresse des Laufwerkes ermitteln.
  }
  var
    bSCSIBuffer : Array[0.. 1023] of AnsiChar;
    pSCSIAddr   : PSCSI_ADDRESS;
    nReturned   : Cardinal;
  begin
    Result := False;
    if aDevice <> INVALID_HANDLE_VALUE
    then begin
      {
      *  Die SCSI Adresse für das Laufwerk ermitteln und eintragen.
      }
      ZeroMemory(@bSCSIBuffer, 1024);
      pscsiAddr := PSCSI_ADDRESS(@bSCSIBuffer);
      pscsiAddr^.Length := SizeOf(TSCSI_ADDRESS);
      Result := DeviceIoControl(aDevice, IOCTL_SCSI_GET_ADDRESS, nil, 0,
                                pscsiAddr, SizeOf(TSCSI_ADDRESS), nReturned, nil);
      if Result
      then begin
        fDrive[fActive].SCSIAddress.Port     := pscsiAddr^.PortNumber;
        fDrive[fActive].SCSIAddress.TargetId := pscsiAddr^.TargetId;
        fDrive[fActive].SCSIAddress.LUnId    := pscsiAddr^.Lun;
      end;
    end;
  end;
          

Die SCSI-Adressen werden in der Demo beispielsweise nach der Ermittlung der Laufwerksbuchstaben geholt. Zum Holen des Handles wird die Funktion DriveHandle aus dem vorigen Kapitel in leicht abgewandelter Form verwendet.

 
  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);
          CloseHandle(hDevice);
        end;
      end;
    end;
  end;
          

Das Ergebnis des Beispiels sieht so aus:

SCSI Address (podSCSIAddress.7z - 226 kb) MD5 (1 kb). Stand: 28. April 2013

Änderungen an der Demo

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