Benutzer mit den meisten Antworten
HW Info

Frage
-
Hi,
ich bin auf der Suche wo ich für Festplatten den Bus Typ (z.B. S-ATA 300) bzw. den Transfer Mode (S-ATA 300 (S-ATA Rev 2.6) auslesen bzw. finden kann?
Bisher habe ich es versucht mit DeviceIoControl -> IOCTL_STORAGE_QUERY_PROPERTY (ergibt nur BusTypeAta) und Win32_DiskDrive (ergibt bei InterfaceType nur IDE). Oder ist diese Information ein zusammengesetzter Wert der sich aus verschiedenen Parameter erst ergibt?
Danke und Gruß
Thomas
Antworten
-
Hallo Thomas,
das Tool CrystalDiskInfo zeigt den Übertragungsmodus und die Schittstelle von Festplatten und SSDs an. Ich habe mal im Sourcecode von CrystalDiskInfo nachgeschaut. Dort wird der Transfer-Modus wie folgt festgestellt:
In Datei AtaSmart.h werden eigene Strukturen definiert, die später an DeviceIoControl() übergeben werden.
struct ATA_IDENTIFY_DEVICE { // ... WORD SerialAtaCapabilities; //76 // ... }; union IDENTIFY_DEVICE { ATA_IDENTIFY_DEVICE A; NVME_IDENTIFY_DEVICE N; BIN_IDENTIFY_DEVICE B; }; typedef struct _SRB_IO_CONTROL { ULONG HeaderLength; UCHAR Signature[8]; ULONG Timeout; ULONG ControlCode; ULONG ReturnCode; ULONG Length; } SRB_IO_CONTROL; typedef struct { SRB_IO_CONTROL sic ; USHORT port ; USHORT maybe_always1 ; ULONG unknown[5] ; //IDENTIFY_DEVICE id_data ; WORD id_data[256] ; } SilIdentDev ; enum IO_CONTROL_CODE { DFP_SEND_DRIVE_COMMAND = 0x0007C084, DFP_RECEIVE_DRIVE_DATA = 0x0007C088, IOCTL_SCSI_MINIPORT = 0x0004D008, IOCTL_IDE_PASS_THROUGH = 0x0004D028, // 2000 or later IOCTL_ATA_PASS_THROUGH = 0x0004D02C, // XP SP2 and 2003 or later };
SPTIUtil.h:
#define IOCTL_SCSI_BASE FILE_DEVICE_CONTROLLER
In Datei AtaSmart.cpp werden die Infos mit DeviceIoControl() ermittelt. In 'data' werden sie zurückgegeben.
BOOL CAtaSmart::DoIdentifyDeviceSi(INT physicalDriveId, INT scsiPort, INT scsiBus, DWORD siliconImageType, IDENTIFY_DEVICE* data) { int done = FALSE; int controller = 0; int current = 0; HANDLE hScsiDriveIOCTL = 0; hScsiDriveIOCTL = GetIoCtrlHandle(scsiPort, siliconImageType); if(hScsiDriveIOCTL != INVALID_HANDLE_VALUE) { SilIdentDev sid; memset(&sid, 0, sizeof(sid)); sid.sic.HeaderLength = sizeof(SRB_IO_CONTROL); memcpy(sid.sic.Signature, "CMD_IDE ", 8); sid.sic.Timeout = 5; sid.sic.ControlCode = CTL_CODE(FILE_DEVICE_CONTROLLER, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS); sid.sic.ReturnCode = 0xffffffff; sid.sic.Length = sizeof(sid) - offsetof(SilIdentDev, port); sid.port = scsiBus; sid.maybe_always1 = 1 ; DWORD dwReturnBytes; if(DeviceIoControl(hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT, &sid, sizeof(sid), &sid, sizeof(sid), &dwReturnBytes, NULL)) { done = TRUE; memcpy_s(data, sizeof(IDENTIFY_DEVICE), &sid.id_data, sizeof(IDENTIFY_DEVICE)); } CloseHandle(hScsiDriveIOCTL); } return done; }
Die Auswertung von 'data' erfolgt in Datei AtaSmart.cpp in Methode CAtaSmart::GetTransferMode(). Dort werden die Flags von data->A.SerialAtaCapabilities abgefragt und die Variablen für Transfer-Modus, Schnittstelle u.a. für die spätere Anzeige entsprechend gesetzt.
data->A ist vom Typ ATA_IDENTIFY_DEVICE.
Ich kann dir nicht sagen, warum die selbst definierten Strukturen in CrystalDiskInfo so aufgebaut sind, wie sie sind. Da müßte man die MSDN zu DeviceIoControl studieren...
Ist schon lange her, daß ich selbst mal was mit der Win32-API gemacht habe. Ich hoffe, meine Recherche hilft dir weiter.
Gruß
Heiko
- Bearbeitet Heiko65456465 Freitag, 28. Dezember 2018 17:37
- Als Antwort markiert Carreat Freitag, 28. Dezember 2018 17:40
Alle Antworten
-
Hallo Thomas,
Was Du herausfinden möchtest, ist eine Besonderheit des physikalischen Busses, während Windows den gleichen SATA-Treiber verwendet, weshalb eine Unterscheidung mithilfe von DeviceIoControl oder Win32_DiskDrive nicht realisierbar ist. Sieh Dir dazu den Kommentar in diesem Thread an.
Gruß,
DimitarBitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.
-
Hallo Thomas,
das Tool CrystalDiskInfo zeigt den Übertragungsmodus und die Schittstelle von Festplatten und SSDs an. Ich habe mal im Sourcecode von CrystalDiskInfo nachgeschaut. Dort wird der Transfer-Modus wie folgt festgestellt:
In Datei AtaSmart.h werden eigene Strukturen definiert, die später an DeviceIoControl() übergeben werden.
struct ATA_IDENTIFY_DEVICE { // ... WORD SerialAtaCapabilities; //76 // ... }; union IDENTIFY_DEVICE { ATA_IDENTIFY_DEVICE A; NVME_IDENTIFY_DEVICE N; BIN_IDENTIFY_DEVICE B; }; typedef struct _SRB_IO_CONTROL { ULONG HeaderLength; UCHAR Signature[8]; ULONG Timeout; ULONG ControlCode; ULONG ReturnCode; ULONG Length; } SRB_IO_CONTROL; typedef struct { SRB_IO_CONTROL sic ; USHORT port ; USHORT maybe_always1 ; ULONG unknown[5] ; //IDENTIFY_DEVICE id_data ; WORD id_data[256] ; } SilIdentDev ; enum IO_CONTROL_CODE { DFP_SEND_DRIVE_COMMAND = 0x0007C084, DFP_RECEIVE_DRIVE_DATA = 0x0007C088, IOCTL_SCSI_MINIPORT = 0x0004D008, IOCTL_IDE_PASS_THROUGH = 0x0004D028, // 2000 or later IOCTL_ATA_PASS_THROUGH = 0x0004D02C, // XP SP2 and 2003 or later };
SPTIUtil.h:
#define IOCTL_SCSI_BASE FILE_DEVICE_CONTROLLER
In Datei AtaSmart.cpp werden die Infos mit DeviceIoControl() ermittelt. In 'data' werden sie zurückgegeben.
BOOL CAtaSmart::DoIdentifyDeviceSi(INT physicalDriveId, INT scsiPort, INT scsiBus, DWORD siliconImageType, IDENTIFY_DEVICE* data) { int done = FALSE; int controller = 0; int current = 0; HANDLE hScsiDriveIOCTL = 0; hScsiDriveIOCTL = GetIoCtrlHandle(scsiPort, siliconImageType); if(hScsiDriveIOCTL != INVALID_HANDLE_VALUE) { SilIdentDev sid; memset(&sid, 0, sizeof(sid)); sid.sic.HeaderLength = sizeof(SRB_IO_CONTROL); memcpy(sid.sic.Signature, "CMD_IDE ", 8); sid.sic.Timeout = 5; sid.sic.ControlCode = CTL_CODE(FILE_DEVICE_CONTROLLER, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS); sid.sic.ReturnCode = 0xffffffff; sid.sic.Length = sizeof(sid) - offsetof(SilIdentDev, port); sid.port = scsiBus; sid.maybe_always1 = 1 ; DWORD dwReturnBytes; if(DeviceIoControl(hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT, &sid, sizeof(sid), &sid, sizeof(sid), &dwReturnBytes, NULL)) { done = TRUE; memcpy_s(data, sizeof(IDENTIFY_DEVICE), &sid.id_data, sizeof(IDENTIFY_DEVICE)); } CloseHandle(hScsiDriveIOCTL); } return done; }
Die Auswertung von 'data' erfolgt in Datei AtaSmart.cpp in Methode CAtaSmart::GetTransferMode(). Dort werden die Flags von data->A.SerialAtaCapabilities abgefragt und die Variablen für Transfer-Modus, Schnittstelle u.a. für die spätere Anzeige entsprechend gesetzt.
data->A ist vom Typ ATA_IDENTIFY_DEVICE.
Ich kann dir nicht sagen, warum die selbst definierten Strukturen in CrystalDiskInfo so aufgebaut sind, wie sie sind. Da müßte man die MSDN zu DeviceIoControl studieren...
Ist schon lange her, daß ich selbst mal was mit der Win32-API gemacht habe. Ich hoffe, meine Recherche hilft dir weiter.
Gruß
Heiko
- Bearbeitet Heiko65456465 Freitag, 28. Dezember 2018 17:37
- Als Antwort markiert Carreat Freitag, 28. Dezember 2018 17:40