AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi SCSI-Passthrough mit der Funktion DeviceIoControl
Thema durchsuchen
Ansicht
Themen-Optionen

SCSI-Passthrough mit der Funktion DeviceIoControl

Ein Thema von c.wuensch · begonnen am 14. Jul 2008 · letzter Beitrag vom 16. Jul 2008
Antwort Antwort
c.wuensch

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

SCSI-Passthrough mit der Funktion DeviceIoControl

  Alt 14. Jul 2008, 22:23
Hi,

ich habe die Frage hier schonmal gestellt, aber mache jetzt einen neuen Thread, damit der Titel besser passt.

Ich möchte eine SCSI-Festplatt in den Standby-Modus versetzen. Dafür gibt es extra einen SCSI-Befehl Stop Unit, der hier erläutert ist.

Mit der API-Funktion DeviceIoControl lässt sich mit der Konstante IOCTL_SCSI_PASS_THROUGH ein SCSI-Befehl an eine Platte senden.

Mein Problem ist jetzt:
- Wie programmiere ich diesen Aufruf in Delphi?
- Was muss ich da jetzt genau als Parameter übergeben?
- Und bekomme ich einen Rückgabewert, der mir sagt, ob es geklappt hat oder nicht?

Optimal wäre es noch, wenn auch jemand einen SCSI-Befehl wüsste, mit dem man den aktuellen Power-Status der Platte auslesen kann. Angeblich könnte das über den REQUEST SENSE Befehl gehen, ich weiß aber nicht wie...

Freue mich über jede Antwort!
Cu, Chris
  Mit Zitat antworten Zitat
hathor
(Gast)

n/a Beiträge
 
#2

Re: SCSI-Passthrough mit der Funktion DeviceIoControl

  Alt 14. Jul 2008, 23:13
http://www.google.com/codesearch?hl=...CDB&sbtn=Suche
  Mit Zitat antworten Zitat
c.wuensch

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

Re: SCSI-Passthrough mit der Funktion DeviceIoControl

  Alt 14. Jul 2008, 23:46
Da hab ich auch schon geschaut.
Aber das hilft mir leider nicht weiter, denn nichts davon ist (soweit ich feststellen konnte) in Delphi und für Windows geschrieben.
Kann mir das vielleicht jemand verständlicher (also für Dumme ) erklären?
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#4

Re: SCSI-Passthrough mit der Funktion DeviceIoControl

  Alt 15. Jul 2008, 00:17
Moin!

Zitat von c.wuensch:
Aber das hilft mir leider nicht weiter, denn nichts davon ist (soweit ich feststellen konnte) in Delphi und für Windows geschrieben.
Doch, beides für Delphi und beides für Windows.

MfG
Muetze1
  Mit Zitat antworten Zitat
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
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:24 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz