![]() |
SCSI-Passthrough mit der Funktion DeviceIoControl
Hi,
ich habe die Frage ![]() Ich möchte eine SCSI-Festplatt in den Standby-Modus versetzen. Dafür gibt es extra einen SCSI-Befehl Stop Unit, der ![]() 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 |
Re: SCSI-Passthrough mit der Funktion DeviceIoControl
|
Re: SCSI-Passthrough mit der Funktion DeviceIoControl
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? |
Re: SCSI-Passthrough mit der Funktion DeviceIoControl
Moin!
Zitat:
MfG Muetze1 |
Re: SCSI-Passthrough mit der Funktion DeviceIoControl
@Muetze1: Welche "beiden" von den ca. 3.000 Suchergebnissen meinst du jetzt genau? :wiejetzt:
Also, ich hab es jetzt hingekriegt, mit folgendem Code ein SCSI-Kommando auszuführen.
Delphi-Quellcode:
Aber ich weiß immernoch nicht, wie ich die Rückgabe aus dem Buffer in ein (für mich) lesbares Format bekomme :gruebel:
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; Wenn ich es richtig verstehe, liegt dieser als Byte-Array der Länge 32 vor, sollte aber eigentlich folgende Struktur haben:
Delphi-Quellcode:
Kann mir dabei jemand helfen (das sollte doch ein Standard-Problem vieler API-Aufrufe sein, oder?)
//***************************************************************************
// %%% 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; Cu, Chris |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:48 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz