none
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

    Donnerstag, 27. Dezember 2018 10:21

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
    Freitag, 28. Dezember 2018 17:30

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ß,
    Dimitar


    Bitte 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.

    Freitag, 28. Dezember 2018 10:11
    Moderator
  • 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
    Freitag, 28. Dezember 2018 17:30
  • Hi Dimitar,

    danke für die Info!

    Gruß Thomas

    Freitag, 28. Dezember 2018 17:39
  • Hi Heiko,

    vielen Dank - werde mir das mal das genauer anschauen!

    Gruß Thomas

    Freitag, 28. Dezember 2018 17:40