Einzelnen Beitrag anzeigen

c.wuensch

Registriert seit: 19. Dez 2004
Ort: Münster
96 Beiträge
 
#5

Re: SCSI-Passthrough mit der Funktion DeviceIoControl

  Alt 16. Jul 2008, 15:16
@Muetze1: Welche "beiden" von den ca. 3.000 Suchergebnissen meinst du jetzt genau?

Also, ich hab es jetzt hingekriegt, mit folgendem Code ein SCSI-Kommando auszuführen.

Delphi-Quellcode:
function MagWmiScsiDiskInfo (drivenr: integer; var errinfo, model,
                                    serial: string ; var diskbytes: Int64): boolean ;
{$ALIGN ON}  // was bedeutet das?
type
   TScsiPassThrough = record
      Length : Word;
      ScsiStatus : Byte;
      PathId : Byte;
      TargetId : Byte;
      Lun : Byte;
      CdbLength : Byte;
      SenseInfoLength : Byte;
      DataIn : Byte;
      DataTransferLength : ULONG;
      TimeOutValue : ULONG;
      DataBufferOffset : DWORD;
      SenseInfoOffset : ULONG;
      Cdb : Array[0..15] of Byte;
   end;
   TScsiPassThroughWithBuffers = record
      spt : TScsiPassThrough;
      bSenseBuf : Array[0..31] of Byte;
      bDataBuf : Array[0..191] of Byte;
   end;
{ALIGN OFF}

var
  hDevice: THandle ;
   dwReturned: DWORD;
  len: DWORD;
  S: string ;
   Buffer: Array [0..SizeOf (TScsiPassThroughWithBuffers) +
                            SizeOf (TScsiPassThrough) -1 ] of Byte;
   sptwb: TScsiPassThroughWithBuffers absolute Buffer;
begin
   result := false;
  errinfo := '' ;
  S := '\\.\d:';
   hDevice := CreateFile( PChar(S), GENERIC_READ or GENERIC_WRITE,
            FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0 ) ;
  if hDevice = INVALID_HANDLE_VALUE then
    begin
      errinfo := 'Unable to open physical drive: ' + SysErrorMessage (GetLastError) ;
      exit ;
    end ;
  try
   FillChar (Buffer, SizeOf(Buffer), #0) ;
   with sptwb.spt do
   begin
      Length := SizeOf (TScsiPassThrough) ;
      CdbLength := 6 ; // CDB6GENERIC_LENGTH
      SenseInfoLength := 24 ;
      DataIn := 1 ; // SCSI_IOCTL_DATA_IN
      DataTransferLength := 192 ;
      TimeOutValue := 2 ;
      DataBufferOffset := PChar (@sptwb.bDataBuf) - PChar (@sptwb) ;
      SenseInfoOffset := PChar (@sptwb.bSenseBuf) - PChar (@sptwb) ;
      Cdb[0] := $03 ; //   SCSI_REQ_SENSE=$03
      Cdb[1] := $00 ; //   was ist LUN?
      Cdb[4] := 252 ; // 252 Bytes abfragen
   end;
   len := sptwb.spt.DataBufferOffset + sptwb.spt.DataTransferLength;
    result := DeviceIoControl (hDevice, IOCTL_SCSI_PASS_THROUGH, @sptwb, SizeOf(TScsiPassThrough),
                                                         @sptwb, len, dwReturned, nil) ;
    if NOT result then
    begin
         errinfo := 'SCSI_IOCTL Command Failed: ' + SysErrorMessage (GetLastError) ;
         CloseHandle (hDevice) ;
         exit ;
    end ;
    except
        errinfo := 'Exception Getting SCSI Request Sense Info' ;
        result := false ;
    end ;
    CloseHandle (hDevice) ;
end;
Aber ich weiß immernoch nicht, wie ich die Rückgabe aus dem Buffer in ein (für mich) lesbares Format bekomme
Wenn ich es richtig verstehe, liegt dieser als Byte-Array der Länge 32 vor, sollte aber eigentlich folgende Struktur haben:

Delphi-Quellcode:
//***************************************************************************
// %%% Request Sense Data Format %%%
//***************************************************************************

type
  PSENSE_DATA_FMT = ^SENSE_DATA_FMT;
  SENSE_DATA_FMT = record
    ErrorCode: Byte; // Error Code (70H or 71H)
    SegmentNum: Byte; // Number of current segment descriptor
    SenseKey: Byte; // Sense Key(See bit definitions too)
    InfoByte0: Byte; // Information MSB
    InfoByte1: Byte; // Information MID
    InfoByte2: Byte; // Information MID
    InfoByte3: Byte; // Information LSB
    AddSenLen: Byte; // Additional Sense Length
    ComSpecInf0: Byte; // Command Specific Information MSB
    ComSpecInf1: Byte; // Command Specific Information MID
    ComSpecInf2: Byte; // Command Specific Information MID
    ComSpecInf3: Byte; // Command Specific Information LSB
    AddSenseCode: Byte; // Additional Sense Code
    AddSenQual: Byte; // Additional Sense Code Qualifier
    FieldRepUCode: Byte; // Field Replaceable Unit Code
    SenKeySpec15: Byte; // Sense Key Specific 15th byte
    SenKeySpec16: Byte; // Sense Key Specific 16th byte
    SenKeySpec17: Byte; // Sense Key Specific 17th byte
    AddSenseBytes: Byte; // Additional Sense Bytes
  end;
  TSenseDataFormat = SENSE_DATA_FMT;
  PSenseDataFormat = ^TSenseDataFormat;
Kann mir dabei jemand helfen (das sollte doch ein Standard-Problem vieler API-Aufrufe sein, oder?)

Cu, Chris
  Mit Zitat antworten Zitat