![]() |
SSD erkennen?
Hallo,
sicher schon mal gefragt, aber ich finde nix. Wie erkennt man im Programm eigentlich sicher, dass man es mit einer SSD zu tun hat? (D7pro, Win7 64) Danke! Mattze |
AW: SSD erkennen?
_Ich_ denke, dass es dazu keine allgemein gültige Lösung gibt, da SSDs sich als Festplatten ausgeben. Vermutlich musst du über Umwege rausfinden zu versuchen, ob es sich um eine SSD-HD handelt. Anbieten würde sich da z.B.
|
AW: SSD erkennen?
Jupp, es gibt zwar einige standardisierte IDE-Befehle für SSDs, wie z.B.
![]() PS: Es gibt auch Möglichkeiten um Speicherkarten via IDE anzuschließen. (quasi der Vorfahre von SSD) z.B. die ![]() Die sind ja auch nicht sooo langsam, so daß es da mit dem Erkennen, über die Zugriffszeiten nicht so einfach aussieht. |
AW: SSD erkennen?
Hallo,
Kollege von mir meinte vor kurzem SSDs geben bei der Rotationsgeschwindigkeit 0 an wenn man diese abfragt, vielleicht wäre das ja ein Ansatzpunkt für Dich. Bin da nicht weiter drauf eingegangen, empfand es aber als logisch, da drin rotiert ja nix:idea: |
AW: SSD erkennen?
Zitat:
|
AW: SSD erkennen?
Ja, die Rotationsgeschwindigkeit ist das Stichwort. Windows 7 deaktiviert die automatische Datenträgerdefragmentierung für ein Laufwerk, sobald die Rotationsgeschwindigkeit 0 beträgt. Das hat auch den Huintergrund, dass eine Defragmentierung bei SSD's und USB-Sticks eher kontraproduktiv ist.
|
AW: SSD erkennen?
Wozu musst du denn das wissen?
|
AW: SSD erkennen?
Zitat:
![]() |
AW: SSD erkennen?
Zitat:
|
AW: SSD erkennen?
Zitat:
|
AW: SSD erkennen?
Hallo,
vielen Dank für Eure Antworten. Es ist eigentlich nur Interesse und für meinen Versuch, die Hardware auszulesen. Ich wusste nicht, was ich damit lostrete! Ich war eben nur recht verblüfft, als O&O Defrag 12 prof beim (testweisen) Aufruf der SSD gleich ausgab, dass das eine SSD sei und die nicht defragmentiert werden sollte. Und schon kam die Frage: Woher weiß O&O das? Da das ja auch bei allen SSD funktionieren sollte, dachte ich da wirklich, dass es einen allgemeinen Hinweis (z. B. im Controller) gibt! Nebenbei: Es gibt eine Reihe Statusprogramme für SSD (z. B. SSD Life free). Die bieten schon bei der Laufwerkswahl nur SSDs an. Also müssen die das auch irgendwie mitkriegen. Nur: Wie? Nur über die Rotationsgeschwindigkeit würde ja offenbar auch nicht ganz richtig werden. Trotzdem, ein guter Ansatz ist das allemale. Bevor ich nun anfange zu suchen, wie ermittelt man die Rotationsgeschwindigkeit? Gruß Mattze |
AW: SSD erkennen?
Zitat:
Komplett defekte Datenträger kann man zwar vergessen, aber sobal man noch Lesezugriff bekommt, könnten Datenwiederherstellungsprogramme zusammenhängende Dateien besser wiederherstellen. (vorallem wenn Volumebitmaps und Co. defekt sind) PS: Wenn man für SSDs im Programm Optimierungen verbaut hat, warum das dann nicht einfach den Benutzer einstellen lassen? |
AW: SSD erkennen?
Ich habe mal irgendwo gelesen, dass sich SSDs als RAM-Drive anmelden.
GetDriveType müsste bei einer SSD also DRIVE_RAMDISK (6) ausgeben. Habe aber leider keine SSD um das zu testen. |
AW: SSD erkennen?
SSD defragmentieren? Bald kommt der Osterhase!
|
AW: SSD erkennen?
Also bei mir nicht: GetDriveType('C:\') ergibt 3 = dtFixed
|
AW: SSD erkennen?
Wieso sollten die ein RAM-Drive sein?
Das sind spezielle Treiber, für virtuelle Laufwerke. SSD sind an IDE/SATA angeschlossen und werden auch über die normalen Festplattentreiber angesprochen. |
AW: SSD erkennen?
Hallo,
inzwischen habe ich zwar ziemlich gesucht, aber ich finde nix. Wie liest man die Rotationsgeschwindigkeit einer Festplatte im Code aus? Soweit ich das gelesen habe, kann Win 7, laut MS, keine SSD im RAID erkennen. Das deutet darauf hin, dass die wirklich über die Rotationsgeschwindigkeit gehen! Und dann noch Raid testen. Geschwindigkeit = 0, kein RAID --> SSD Geschwindigkeit = 0, RAID --> als HDD erkannt und angesprochen. Gruß Mattze |
AW: SSD erkennen?
Non-rotating media
Windows 7 detects SSDs by using ATA8-ACS identify word 217: Nominal media rotation rate, with value 0001h as Non-rotating media like solid state devices. But not all SSDs adhere to the ATA8-ACS1 spec section 7.16.7.77, some may need firmware updates. Seek Time Unlike a magnetic rotating disk, the SSD has no read/write heads or platter. There is no seek time or rotational latency issues. Zeus SSDs dramatically improve transaction throughput, particularly for applications that are configured to take advantage of the characteristics of the drive. WINDOWS 7 The random read threshold test was added to the final product to address the fact that few SSDs on the market today properly identify themselves as SSDs. 8 MB/sec is a relatively conservative rate. While none of our tested HDDs could approach 8 MB/sec, all of our tested SSDs exceeded that threshold. SSD performance ranged between 11 MB/sec and 130 MB/sec. Of the 182 HDDs tested, only 6 configurations managed to exceed 2 MB/sec on our random read test. The other 176 ranged between 0.8 MB/sec and 1.6 MB/sec. ![]() |
AW: SSD erkennen?
Vielen Dank, hathor.
Das ist doch schon was. Nun müsste ich nur noch wissen, wie ich das ATA8-ACS, Word 217 mit Delphi (7 pro) auslesen kann. Hast Du einen Tipp? Und die Frage ganz allgemein, weil es mich interessiert, wie man die Rotationsgeschwindigkeit einer Platte auslesen kann. Danke! Mattze |
AW: SSD erkennen?
Hier übrigens die passende ATA Spezifikation T13/e06176r1, die du hier in der Liste findest:
![]() Der direkte Link: ![]() Auslesen kannst du das mit ![]() ![]() |
AW: SSD erkennen?
Vielen Dank und Au-weiha!
Ich werde wohl langsam alt! Vielleicht nicht direkt das, aber mit diesen Dingen habe ich doch schon gearbeitet als ich die ganzen Speicher und deren Herstellerbezeichnung (und ein paar Daten) auslesen wollte. Ich muss dringend etwas tun, damit mein Hirn nicht ganz einrostet! Gruß Mattze |
AW: SSD erkennen?
Hallo,
ich komme leider erst jetzt wieder dazu, mich damit weiter zu beschäftigen und... ich finde es nicht! Ich kriege die Rotationsgeschwindigkeit einfach nicht raus. Irgendwann, als ich mich mit DeviceIoControl näher beschäftigt habe, habe ich mal etwas davon gelesen - bin ich mir sicher. Nun finde ich es nicht mehr. In der Struktur für IOCTL_ATA_PASS_THROUGH finde ich auch nix. Für einen kleiner Tipp wäre ich dankbar. Gruß Mattze |
AW: SSD erkennen?
Ja, jetzt sind ja schlappe 4 Jährchen vergangen, ob Mattze immer noch über der Antwort brütet?
Jedenfalls brauchte ich auch eine funktionierende SSD-Erkennung und habe mich mal ungeniert ![]() Das funktioniert auch, hat aber einen großen Pferdefuß: Man braucht Administratorrechte für das CreateFile. Kennt jemand eine Lösung, wo es auch ohne geht? Oder ist das prinzipiell unmöglich?
Delphi-Quellcode:
uses Winapi.Windows,System.SysUtils,System.Types,System.UITypes,Vcl.Dialogs;
type { ATA_PASS_THROUGH_EX } _ATA_PASS_THROUGH_EX = packed record Length: Word; AtaFlags: Word; PathId: UCHAR; TargetId: UCHAR; Lun: UCHAR; ReservedAsUchar: UCHAR; DataTransferLength: ULONG; TimeOutValue: ULONG; ReservedAsUlong: ULONG; DataBufferOffset: ULONG_PTR; PreviousTaskFile: array [0..7] of UCHAR; CurrentTaskFile: array [0..7] of UCHAR; end; {$EXTERNALSYM _ATA_PASS_THROUGH_EX} ATA_PASS_THROUGH_EX = _ATA_PASS_THROUGH_EX; {$EXTERNALSYM ATA_PASS_THROUGH_EX} TAtaPassThroughEx = _ATA_PASS_THROUGH_EX; PAtaPassThroughEx = ^TAtaPassThroughEx; { ATAIdentifyDeviceQuery } TATAIdentifyDeviceQuery = packed record header: ATA_PASS_THROUGH_EX; data: array [0..255] of Word; end; const {$IF RTLVersion < 22.0} FILE_DEVICE_CONTROLLER = $00000004; {$EXTERNALSYM FILE_DEVICE_CONTROLLER} FILE_READ_ACCESS = $0001; {$EXTERNALSYM FILE_READ_ACCESS} FILE_WRITE_ACCESS = $0002; {$EXTERNALSYM FILE_WRITE_ACCESS} {$IFEND} ATA_FLAGS_DRDY_REQUIRED = $01; ATA_FLAGS_DATA_IN = $02; ATA_FLAGS_DATA_OUT = $04; ATA_FLAGS_48BIT_COMMAND = $08; ATA_FLAGS_USE_DMA = $10; ATA_FLAGS_NO_MULTIPLE = $20; IOCTL_SCSI_BASE = FILE_DEVICE_CONTROLLER; IOCTL_ATA_PASS_THROUGH = (IOCTL_SCSI_BASE shl 16) or ((FILE_READ_ACCESS or FILE_WRITE_ACCESS) shl 14) or ($040B shl 2) or (METHOD_BUFFERED); {$IF RTLversion < 22.0} const FILE_READ_DATA = $0001; {$EXTERNALSYM FILE_READ_DATA} FILE_READ_ATTRIBUTES = $0080; {$EXTERNALSYM FILE_READ_ATTRIBUTES} FILE_DEVICE_MASS_STORAGE = $0000002d; {$EXTERNALSYM FILE_DEVICE_MASS_STORAGE} IOCTL_STORAGE_BASE = FILE_DEVICE_MASS_STORAGE; {$EXTERNALSYM IOCTL_STORAGE_BASE} FILE_ANY_ACCESS = 0; {$EXTERNALSYM FILE_ANY_ACCESS} METHOD_BUFFERED = 0; {$EXTERNALSYM METHOD_BUFFERED} IOCTL_STORAGE_QUERY_PROPERTY = (IOCTL_STORAGE_BASE shl 16) or (FILE_ANY_ACCESS shl 14) or ($0500 shl 2) or (METHOD_BUFFERED); {$EXTERNALSYM IOCTL_STORAGE_QUERY_PROPERTY} {$IFEND} type { STORAGE_PROPERTY_ID } _STORAGE_PROPERTY_ID = ( StorageDeviceProperty = 0, StorageAdapterProperty = 1, StorageDeviceIdProperty = 2, StorageDeviceUniqueIdProperty = 3, StorageDeviceWriteCacheProperty = 4, StorageMiniportProperty = 5, StorageAccessAlignmentProperty = 6, StorageDeviceSeekPenaltyProperty = 7, StorageDeviceTrimProperty = 8, StorageDeviceWriteAggregationProperty = 9, StorageDeviceDeviceTelemetryProperty = 10 ); {$EXTERNALSYM _STORAGE_PROPERTY_ID} STORAGE_PROPERTY_ID = _STORAGE_PROPERTY_ID; {$EXTERNALSYM STORAGE_PROPERTY_ID} TStoragePropertyId = _STORAGE_PROPERTY_ID; PStoragePropertyId = ^TStoragePropertyId; { STORAGE_QUERY_TYPE } _STORAGE_QUERY_TYPE = ( PropertyStandardQuery = 0, PropertyExistsQuery = 1, PropertyMaskQuery = 2, PropertyQueryMaxDefined = 3 ); {$EXTERNALSYM _STORAGE_QUERY_TYPE} STORAGE_QUERY_TYPE = _STORAGE_QUERY_TYPE; {$EXTERNALSYM STORAGE_QUERY_TYPE} TStorageQueryType = _STORAGE_QUERY_TYPE; PStorageQueryType = ^TStorageQueryType; { STORAGE_PROPERTY_QUERY } _STORAGE_PROPERTY_QUERY = packed record PropertyId: DWORD; QueryType: DWORD; AdditionalParameters: array[0..9] of Byte; end; {$EXTERNALSYM _STORAGE_PROPERTY_QUERY} STORAGE_PROPERTY_QUERY = _STORAGE_PROPERTY_QUERY; {$EXTERNALSYM STORAGE_PROPERTY_QUERY} TStoragePropertyQuery = _STORAGE_PROPERTY_QUERY; PStoragePropertyQuery = ^TStoragePropertyQuery; { DEVICE_SEEK_PENALTY_DESCRIPTOR } _DEVICE_SEEK_PENALTY_DESCRIPTOR = packed record Version: DWORD; Size: DWORD; IncursSeekPenalty: ByteBool; Reserved: array[0..2] of Byte; end; {$EXTERNALSYM _DEVICE_SEEK_PENALTY_DESCRIPTOR} DEVICE_SEEK_PENALTY_DESCRIPTOR = _DEVICE_SEEK_PENALTY_DESCRIPTOR; {$EXTERNALSYM DEVICE_SEEK_PENALTY_DESCRIPTOR} TDeviceSeekPenaltyDescriptor = _DEVICE_SEEK_PENALTY_DESCRIPTOR; PDeviceSeekPenaltyDescriptor = ^TDeviceSeekPenaltyDescriptor; type { DISK_EXTENT } _DISK_EXTENT = packed record DiskNumber: DWORD; StartingOffset: LARGE_INTEGER; ExtentLength: LARGE_INTEGER; Reserved: array [0..3] of Byte; end; {$EXTERNALSYM _DISK_EXTENT} DISK_EXTENT = _DISK_EXTENT; {$EXTERNALSYM DISK_EXTENT} TDiskExtent = _DISK_EXTENT; PDiskExtent = ^TDiskExtent; { VOLUME_DISK_EXTENTS } _VOLUME_DISK_EXTENTS = packed record NumberOfDiskExtents: DWORD; Reserved: array [0..3] of Byte; Extents: array [0..0] of DISK_EXTENT; end; {$EXTERNALSYM _VOLUME_DISK_EXTENTS} VOLUME_DISK_EXTENTS = _VOLUME_DISK_EXTENTS; {$EXTERNALSYM VOLUME_DISK_EXTENTS} TVolumeDiskExtents = VOLUME_DISK_EXTENTS; PVolumeDiskExtents = ^TVolumeDiskExtents; {$IF RTLVersion < 22.0} const IOCTL_VOLUME_BASE = $00000056; {$EXTERNALSYM IOCTL_VOLUME_BASE} IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = (IOCTL_VOLUME_BASE shl 16) or (FILE_ANY_ACCESS shl 14) or (0 shl 2) or (METHOD_BUFFERED); {$EXTERNALSYM IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS} {$IFEND} function HasNominalMediaRotationRate(const PhysicalDrivePath: String): Boolean; function HasNoSeekPenalty(const PhysicalDrivePath: String): Boolean; procedure PathnameToPhysicalDriveNumber(const Path: String; var PhysicalDrives: TIntegerDynArray); function IstSSD(LW:Char):Boolean; implementation function HasNominalMediaRotationRate(const PhysicalDrivePath: String): Boolean; var h: THandle; ATAIdentifyDeviceQuery: TATAIdentifyDeviceQuery; RSize: DWORD; begin h := CreateFile(PChar(PhysicalDrivePath),GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE,nil, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); if h = INVALID_HANDLE_VALUE then begin RaiseLastOSError; end; try FillChar(ATAIdentifyDeviceQuery,SizeOf(ATAIdentifyDeviceQuery),0); with ATAIdentifyDeviceQuery do begin header.Length := SizeOf(header); header.AtaFlags := ATA_FLAGS_DATA_IN; header.DataTransferLength := SizeOf(data); header.TimeOutValue := 3; // sec header.DataBufferOffset := SizeOf(header); header.CurrentTaskFile[6] := $EC; // ATA IDENTIFY DEVICE command end; RSize := 0; if DeviceIoControl(h,IOCTL_ATA_PASS_THROUGH, @ATAIdentifyDeviceQuery,SizeOf(ATAIdentifyDeviceQuery), @ATAIdentifyDeviceQuery,SizeOf(ATAIdentifyDeviceQuery), RSize,nil) = False then begin RaiseLastOSError; end; Result := (ATAIdentifyDeviceQuery.data[217] = 1); finally CloseHandle(h); end; end; function HasNoSeekPenalty(const PhysicalDrivePath: String): Boolean; var h :THandle; StoragePropertyQuery: TStoragePropertyQuery; DeviceSeekPenaltyDescriptor: TDeviceSeekPenaltyDescriptor; RSize: DWORD; begin h := CreateFile(PChar(PhysicalDrivePath),FILE_READ_ATTRIBUTES, FILE_SHARE_READ or FILE_SHARE_WRITE,nil, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); if h = INVALID_HANDLE_VALUE then begin RaiseLastOSError; end; try with StoragePropertyQuery do begin PropertyId := Ord(StorageDeviceSeekPenaltyProperty); QueryType := Ord(PropertyStandardQuery); end; FillChar(DeviceSeekPenaltyDescriptor,SizeOf(DeviceSeekPenaltyDescriptor),0); RSize := 0; if DeviceIoControl(h,IOCTL_STORAGE_QUERY_PROPERTY, @StoragePropertyQuery,SizeOf(StoragePropertyQuery), @DeviceSeekPenaltyDescriptor,SizeOf(DeviceSeekPenaltyDescriptor), RSize,nil) = False then begin RaiseLastOSError; end; Result := not DeviceSeekPenaltyDescriptor.IncursSeekPenalty; finally CloseHandle(h); end; end; procedure PathnameToPhysicalDriveNumber(const Path: String; var PhysicalDrives: TIntegerDynArray); var h: THandle; I: Integer; MountPoint: String; VolumeName: String; Size: DWORD; RSize: DWORD; P: PVolumeDiskExtents; lpFilePart : PWideChar; lpBuffer : PWideChar; begin SetLength(PhysicalDrives,0); lpBuffer := nil; { Pathname to mount point } Size := GetFullPathName(PWideChar(Path),0,lpBuffer,lpFilePart); SetLength(MountPoint,Size); if GetVolumePathName(PAnsiChar(Path),PAnsiChar(MountPoint),Size) = False then begin RaiseLastOSError; end; SetLength(MountPoint,StrLen(PWideChar(MountPoint))); { Mount point to logical volume name } Size := 50; // Recomended size from http://msdn.microsoft.com/en-us/library/windows/desktop/aa364994.aspx SetLength(VolumeName,Size); if GetVolumeNameForVolumeMountPoint(PAnsiChar(MountPoint),PAnsiChar(VolumeName),Size) = False then begin RaiseLastOSError; end; SetLength(VolumeName,StrLen(PChar(VolumeName))); VolumeName := ExcludeTrailingPathDelimiter(VolumeName); { Open volume } h := CreateFile(PChar(VolumeName),FILE_READ_ATTRIBUTES, FILE_SHARE_READ or FILE_SHARE_WRITE,nil, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); if h = INVALID_HANDLE_VALUE then begin RaiseLastOSError; end; try Size := SizeOf(TVolumeDiskExtents); P := AllocMem(Size); try FillChar(P^,Size,0); RSize := 0; if DeviceIoControl(h,IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, nil,0, P,Size, RSize,nil) = False then begin if GetLastError <> ERROR_MORE_DATA then begin RaiseLastOSError; end; Size := SizeOf(TVolumeDiskExtents) + SizeOf(DISK_EXTENT) * (P^.NumberOfDiskExtents - 1); ReallocMem(P,Size); FillChar(P^,Size,0); if DeviceIoControl(h,IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, nil,0, P,Size, RSize,nil) = False then begin RaiseLastOSError; end; end; SetLength(PhysicalDrives,P^.NumberOfDiskExtents); for I := 0 to P^.NumberOfDiskExtents - 1 do begin PhysicalDrives[I] := P^.Extents[I].DiskNumber; end; finally FreeMem(P); end; finally CloseHandle(h); end; end; function IstSSD(LW:Char):Boolean; var Index: Integer; Filename: String; PhysicalDrives: TIntegerDynArray; PhysicalDrivePath: String; IsSSD: Boolean; begin Result := False; Filename := LW + ':\'; SetLength(PhysicalDrives,0); PathnameToPhysicalDriveNumber(Filename,PhysicalDrives); try IsSSD := False; for Index := Low(PhysicalDrives) to High(PhysicalDrives) do begin PhysicalDrivePath := Format('\\.\PhysicalDrive%d',[PhysicalDrives[Index]]); try IsSSD := IsSSD or HasNominalMediaRotationRate(PhysicalDrivePath); except { Ignore } end; if IsSSD = True then begin exit(True); end; end; finally SetLength(PhysicalDrives,0); end; end; end. |
AW: SSD erkennen?
Es gibt S.M.A.R.T.-Werte, die nur bei SSD vorhanden sind, z.B.
230, E6, Drive Life Protection Status: 100 (protection is not active) oder 90 (protection is active) 231, E7, SSD Life Left 1-100 % Info: MKP_306_SMART_attribute.pdf |
AW: SSD erkennen?
Leider ist es so, dass sich die Hersteller nicht an standardisierte S.M.A.R.T.-Werte halten. Bei der
![]() |
AW: SSD erkennen?
Ich habe den Code von Benmik getestet und merkwürdigerweise funktioniert er nur auf meinem Windows 10 PC. Auf einem Windows 7 PC mit der gleichen SSD bekomme ich hier:
Delphi-Quellcode:
den Fehler: The program issued a command but the command length is incorrect.
if DeviceIoControl(h,IOCTL_ATA_PASS_THROUGH,
@ATAIdentifyDeviceQuery,SizeOf(ATAIdentifyDeviceQuery), @ATAIdentifyDeviceQuery,SizeOf(ATAIdentifyDeviceQuery), RSize,nil) = False then begin RaiseLastOSError; end; Ich vermute dass diese Struktur:
Delphi-Quellcode:
nicht ganz richtig ist.
IOCTL_ATA_PASS_THROUGH = (IOCTL_SCSI_BASE shl 16) or
((FILE_READ_ACCESS or FILE_WRITE_ACCESS) shl 14) or ($040B shl 2) or (METHOD_BUFFERED); Für Hilfe wäre ich dankbar. |
AW: SSD erkennen?
Hab einen Fix gefunden:
Delphi-Quellcode:
{ ATAIdentifyDeviceQuery }
TATAIdentifyDeviceQuery = packed record header: ATA_PASS_THROUGH_EX; data: array [0..8191] of Word; end; |
AW: SSD erkennen?
Hallo,
so mache ich das nun seit langer Zeit auch. Allerdings reichen bei mir 255 Worte.
Delphi-Quellcode:
Bisher hatte ich damit keine Probleme (Win 7, 8, 8.1, 10. Alles pro und 64Bit. Übersetzt mit Delphi 7 pro, also 32 Bit)
// ATA_PASS_THROUGH_EX
_ATA_PASS_THROUGH_EX = packed record Length: Word; AtaFlags: Word; PathId: UChar; TargetId: UCHAR; Lun: UCHAR; ReservedAsUchar: UCHAR; DataTransferLength: ULONG; TimeOutValue: ULONG; ReservedAsUlong: ULONG; DataBufferOffset: ULONG_PTR; PreviousTaskFile: array [0..7] of UCHAR; CurrentTaskFile: array [0..7] of UCHAR; end; {$EXTERNALSYM _ATA_PASS_THROUGH_EX} ATA_PASS_THROUGH_EX = _ATA_PASS_THROUGH_EX; {$EXTERNALSYM ATA_PASS_THROUGH_EX} TAtaPassThroughEx = _ATA_PASS_THROUGH_EX; PAtaPassThroughEx = ^TAtaPassThroughEx; // ATAIdentifyDeviceQuery TATAIdentifyDeviceQuery = packed record header: ATA_PASS_THROUGH_EX; data: array [0..255] of Word; end; Gruß Mattze |
AW: SSD erkennen?
Aber an der Notwendigkeit der Administratorrechte hat sich nichts geändert?
|
AW: SSD erkennen?
Ab WINDOWS8 gibt es über WMI mehr Informationen, siehe:
![]() MediaType Data type: UInt16 Access type: Read-only The media type of the physical disk. Value Meaning 0 Unspecified 3 HDD 4 SSD SpindleSpeed Data type: UInt32 Access type: Read-only Qualifiers: Required, Units ("RPM") The rotational speed of spindle-based physical disks. For solid state devices (SSDs) or other non-rotational media, this member should be set to 0. For rotating media that has an unknown speed, this member should be set to 0xFFFFFFFF (UINT32_MAX). Beispiel geht auch OHNE Administrator-Rechte und bei USB-Disks.
Delphi-Quellcode:
Beispiel-Ausgabe: PhysicalDisk1 = SSD/USB, PhysicalDisk0 = HDD0
// This code was generated by the Wmi Delphi Code Creator http://theroadtodelphi.wordpress.com
// Version: 1.8.3.0 // LIABILITY DISCLAIMER // THIS GENERATED CODE IS DISTRIBUTED "AS IS". NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. // YOU USE IT AT YOUR OWN RISK. THE AUTHOR NOT WILL BE LIABLE FOR DATA LOSS, // DAMAGES AND LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING OR MISUSING THIS CODE. program WMI_PhysicalDisk; {$APPTYPE CONSOLE} uses // SysUtils, ActiveX, ComObj, Variants; System.SysUtils, Winapi.ActiveX, System.Win.ComObj, System.Variants; function VarToInt(const AVariant: Variant): INT64;// integer; begin Result := StrToIntDef(Trim(VarToStr(AVariant)), 0); end; procedure GetMSFT_PhysicalDiskInfo; const WbemUser =''; WbemPassword =''; WbemComputer ='localhost'; wbemFlagForwardOnly = $00000020; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject : OLEVariant; oEnum : IEnumvariant; iValue : LongWord; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\Microsoft\Windows\Storage', WbemUser, WbemPassword); FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM MSFT_PhysicalDisk','WQL',wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant; while oEnum.Next(1, FWbemObject, iValue) = 0 do begin Writeln(Format('AllocatedSize %d',[VarToInt(FWbemObject.AllocatedSize)]));// Uint64 Writeln(Format('BusType %d',[VarToInt(FWbemObject.BusType)]));// Uint16 // Writeln(Format('CannotPoolReason %d',[VarToInt(FWbemObject.CannotPoolReason)]));// Array of Uint16 Writeln(Format('CanPool %s',[VarToStr(FWbemObject.CanPool)]));// Boolean Writeln(Format('Description %s',[VarToStr(FWbemObject.Description)]));// String Writeln(Format('DeviceId %s',[VarToStr(FWbemObject.DeviceId)]));// String Writeln(Format('EnclosureNumber %d',[VarToInt(FWbemObject.EnclosureNumber)]));// Uint16 Writeln(Format('FirmwareVersion %s',[VarToStr(FWbemObject.FirmwareVersion)]));// String Writeln(Format('FriendlyName %s',[VarToStr(FWbemObject.FriendlyName)]));// String Writeln(Format('HealthStatus %d',[VarToInt(FWbemObject.HealthStatus)]));// Uint16 Writeln(Format('IsIndicationEnabled %s',[VarToStr(FWbemObject.IsIndicationEnabled)]));// Boolean Writeln(Format('IsPartial %s',[VarToStr(FWbemObject.IsPartial)]));// Boolean Writeln(Format('LogicalSectorSize %d',[VarToInt(FWbemObject.LogicalSectorSize)]));// Uint64 Writeln(Format('Manufacturer %s',[VarToStr(FWbemObject.Manufacturer)]));// String Writeln(Format('MediaType %d',[VarToInt(FWbemObject.MediaType)]));// Uint16 Writeln(Format('Model %s',[VarToStr(FWbemObject.Model)]));// String Writeln(Format('ObjectId %s',[VarToStr(FWbemObject.ObjectId)]));// String // Writeln(Format('OperationalStatus %d',[VarToInt(FWbemObject.OperationalStatus)]));// Array of Uint16 Writeln(Format('OtherCannotPoolReasonDescription %s',[VarToStr(FWbemObject.OtherCannotPoolReasonDescription)]));// String Writeln(Format('PartNumber %s',[VarToStr(FWbemObject.PartNumber)]));// String Writeln(Format('PassThroughClass %s',[VarToStr(FWbemObject.PassThroughClass)]));// String Writeln(Format('PassThroughIds %s',[VarToStr(FWbemObject.PassThroughIds)]));// String Writeln(Format('PassThroughNamespace %s',[VarToStr(FWbemObject.PassThroughNamespace)]));// String Writeln(Format('PassThroughServer %s',[VarToStr(FWbemObject.PassThroughServer)]));// String Writeln(Format('PhysicalLocation %s',[VarToStr(FWbemObject.PhysicalLocation)]));// String Writeln(Format('PhysicalSectorSize %d',[VarToInt(FWbemObject.PhysicalSectorSize)]));// Uint64 Writeln(Format('SerialNumber %s',[VarToStr(FWbemObject.SerialNumber)]));// String Writeln(Format('Size %d',[VarToInt(FWbemObject.Size)]));// Uint64 Writeln(Format('SlotNumber %d',[VarToInt(FWbemObject.SlotNumber)]));// Uint16 Writeln(Format('SoftwareVersion %s',[VarToStr(FWbemObject.SoftwareVersion)]));// String Writeln(Format('SpindleSpeed %d',[VarToInt(FWbemObject.SpindleSpeed)]));// Uint32 // Writeln(Format('SupportedUsages %d',[VarToInt(FWbemObject.SupportedUsages)]));// Array of Uint16 Writeln(Format('UniqueId %s',[VarToStr(FWbemObject.UniqueId)]));// String Writeln(Format('Usage %d',[VarToInt(FWbemObject.Usage)]));// Uint16 Writeln('-------------------------------------------------------------------'); FWbemObject:=Unassigned; end; end; begin try CoInitialize(nil); try GetMSFT_PhysicalDiskInfo; finally CoUninitialize; end; except on E:EOleException do Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode])); on E:Exception do Writeln(E.Classname, ':', E.Message); end; Writeln('Press Enter to exit'); Readln; end. AllocatedSize 0 BusType 7 CanPool False Description DeviceId 1 EnclosureNumber 0 FirmwareVersion 3004 FriendlyName PhysicalDisk1 HealthStatus 0 IsIndicationEnabled IsPartial True LogicalSectorSize 512 Manufacturer KINGSTON MediaType 0 Model SV300S37A240G OtherCannotPoolReasonDescription PartNumber PassThroughClass PassThroughIds PassThroughNamespace PassThroughServer PhysicalLocation PhysicalSectorSize 512 SerialNumber 00A1234xxxxxx Size 0 SlotNumber 0 SoftwareVersion SpindleSpeed -1 UniqueId Usage 1 -------------------------------------------------- AllocatedSize 0 BusType 11 CanPool False Description DeviceId 0 EnclosureNumber 0 FirmwareVersion 2BC10001 FriendlyName PhysicalDisk0 HealthStatus 0 IsIndicationEnabled IsPartial True LogicalSectorSize 512 Manufacturer MediaType 3 Model ST2000LM003 HN-M201RAD OtherCannotPoolReasonDescription PartNumber PassThroughClass PassThroughIds PassThroughNamespace PassThroughServer PhysicalLocation PhysicalSectorSize 4096 SerialNumber S346J9xxxxxxxx Size 0 SlotNumber 0 SoftwareVersion SpindleSpeed -1 UniqueId 50004xxxxxxxxx Usage 1 -------------------------------------------------- |
AW: SSD erkennen?
Ich möchte von der Benutzung von DeviceIoControl() warnen. Hab den Code von hier an 250 Beta Tester geschickt. Auf 5 Systemen dauert die Ausführung von DeviceIoControl() satte 3 Minuten. Dabei bleibt Windows stehen (Mauszeiger bewegt sich nicht). Nach den 3 Minuten gibt die Funktion ein Success zurück und alles geht wie gehabt weiter. Die User mit den Problem haben SSDs von Samsung (unterschiedliche) und von Corsair. Ich kann das Problem auf keinem von meinen Systemen reproduzieren, weiß nur von Debuglogs was los war. Von den Usern haben 4 Windows 10 und einer Windows 7.
|
AW: SSD erkennen?
Ich habe gerade mal den WMI Code Creator rausgekramt und versucht herauszubekommen woran man unter Windows 7 erkennen kann, was eine HDD und was eine SSD ist.
Bis auf die völlig stupide Prüfung, ob "SSD" im Modellnamen vorkommt, wüsste ich nichts. Ich würde ja gerne die RPM oder Zugriffszeit messen habe aber keine Ahnung wie. |
AW: SSD erkennen?
Wie wohl Windows beim Installieren erkennt, ob es auf einer SSD installiert wird? (für die Aktivierung des TRIM)
Die Windows-Defragmentierung beachtet das doch auch irgendwie? Und was ist mit Hybrid-Laufwerken? |
AW: SSD erkennen?
Ich kann gerade nicht unterscheiden, ob es sich bei deinem Beitrag um Ironie handelt oder nicht :stupid:
|
AW: SSD erkennen?
Abseits der Frage, ob man bei himitsu Ironie erkennen kann, verstehe ich deine Frage nicht: Mit Admin-Rechten kann man doch eine SSD erkennen ?!
|
AW: SSD erkennen?
Ja und die Frage ist jetzt wohl wie das Windows macht, damit man es in einem eigenen Programm nutzen kann.
|
AW: SSD erkennen?
Die Adminrechte sind eine große Hürde. Ohne funktioniert das wahrscheinlich nicht?
|
AW: SSD erkennen?
Du hast dir jetzt aber nicht die Diskussion durchgelesen? Mit genau dieser Frage habe ich seinerzeit diesen Thread reanimiert.
|
AW: SSD erkennen?
Ich habe den Thread mehr oder weniger schnell überflogen und weiß, dass es mit Administratorrechten wohl funktioniert, per SMART (nicht zwingend), es aber auch zu Problemen führen kann bei bestimmten SSDs... schwieriges Thema wie es scheint.
|
AW: SSD erkennen?
Vielleicht hast du dir selbst die Antwort gegeben. Es ist zwar "bäh", aber
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:43 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