Autor |
Beitrag |
t.roller
Beiträge: 118
Erhaltene Danke: 34
|
Verfasst: Di 06.06.17 09:53
C: Der Vorgang wurde erfolgreich beendet // unterstützt SMART
USB-DRIVES:
H: Die Anforderung konnte wegen eines E/A-Gerätefehlers nicht ausgeführt werden // unterstützt nicht SMART
Erneuter Aufruf:
H: Die angeforderte Ressource wird bereits verwendet // unterstützt nicht SMART
G: Die Anforderung wird nicht unterstützt // unterstützt SMART
Alles sehr rätselhaft.
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 06.06.17 09:57
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
Delphi-Laie
Beiträge: 1600
Erhaltene Danke: 232
Delphi 2 - RAD-Studio 10.1 Berlin
|
Verfasst: Di 06.06.17 11:09
|
|
t.roller
Beiträge: 118
Erhaltene Danke: 34
|
Verfasst: Di 06.06.17 12:03
Delphi-Laie hat folgendes geschrieben : | Oder anders, ist SMART nicht längst Standard, ohne den keine Festplatte heutzutage mehr hergestellt wird? |
Jede HDD hat SMART, aber ob man die Werte auslesen kann, liegt am S-ATA-Contoller bzw. an der USB-Bridge.
Für diesen Beitrag haben gedankt: Delphi-Laie
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mi 07.06.17 02:02
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
Holgerx
Beiträge: 63
Erhaltene Danke: 27
Win95 - Win11 / MSServer2000 - MSServer2019
Delphi 6pro / XE4
|
Verfasst: Do 08.06.17 19:09
Hmm..
Also an HOME liegt es nicht..
Habe hier WIndows 8.1 Home..
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| [#] Laufwerk C (Festplatte) HandleError = 0 SmartVersionError = 5 SmartDataError = 5 [#] Laufwerk D (Festplatte) HandleError = 0 SmartVersionError = 5 SmartDataError = 5 [#] Laufwerk E (Festplatte) HandleError = 0 SmartVersionError = 5 SmartDataError = 5 [#] Laufwerk F HandleError = 0 SmartVersionError = 1 SmartDataError = 1 [#] Laufwerk G (Festplatte) HandleError = 0 SmartVersionError = 1117 SmartDataError = 1117 [#] Laufwerk Z HandleError = 0 SmartVersionError = 1 SmartDataError = 1 |
Was deine Fehlercodes bedeuten kann ich nicht sagen, jedoch habe ich eine eigene Routine (mit D6), welche mir die gültigen SMART- Werte liefert.
Ich habe sie mal angehängt, ist eine Kombination aus diversen Beiträgen aus verschiedenen Foren und Techdocs von HD-Herstellern.
Einloggen, um Attachments anzusehen!
|
|
t.roller
Beiträge: 118
Erhaltene Danke: 34
|
Verfasst: Do 08.06.17 19:25
WIN8.1 Version 6.3, Build 9600
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| [#] Laufwerk C (Festplatte) HandleError = 0 SmartVersionError = 5 SmartDataError = 5 [#] Laufwerk D (Festplatte) HandleError = 0 SmartVersionError = 5 SmartDataError = 5 [#] Laufwerk E (Festplatte) HandleError = 0 SmartVersionError = 5 SmartDataError = 5 [#] Laufwerk F (Festplatte) HandleError = 0 SmartVersionError = 5 SmartDataError = 5 [#] Laufwerk H (Festplatte) = USB-DISK HandleError = 0 SmartVersionError = 1117 SmartDataError = 1117 [#] Laufwerk I HandleError = 0 SmartVersionError = 1 SmartDataError = 1 |
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 09.06.17 00:22
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
Holgerx
Beiträge: 63
Erhaltene Danke: 27
Win95 - Win11 / MSServer2000 - MSServer2019
Delphi 6pro / XE4
|
Verfasst: Fr 09.06.17 05:24
Hmm..
Ich glaube, das Problem deiner Routinen ist die falsche Fehlerbehandlung!
Delphi-Quelltext 1: 2: 3:
| DeviceIoControl(hDrive, SMART_GET_VERSION, nil, 0, @gvParams, SizeOf(gvParams), bytesReturned, nil); result := GetLastError; |
Nur wenn DeviceIoControl 'fehlschlägt' kann mit GetLastError der dazu gehörende Fehler ausgelesen werden!
Ansonsten kann da irgend ein alter Fehlercode drinnen stehen!
also:
Delphi-Quelltext 1: 2: 3: 4: 5:
| Result := 0; if not DeviceIoControl(hDrive, SMART_GET_VERSION, nil, 0, @gvParams, SizeOf(gvParams), bytesReturned, nil) then result := GetLastError; |
Dann sollte es richtig klappen
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 09.06.17 06:46
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
Holgerx
Beiträge: 63
Erhaltene Danke: 27
Win95 - Win11 / MSServer2000 - MSServer2019
Delphi 6pro / XE4
|
Verfasst: Fr 09.06.17 08:07
Hmm..
Frühlingsrolle hat folgendes geschrieben : | Das geht schon in Ordnung. Der Test soll nur zeigen, ob DeviceIoControl() erfolgreich war. In dem Fall ist GetLastError() = 0, ansonsten größer 0. So erfahre ich, warum es nicht geht, im gegebenen Fall. |
Ob dass so stimmt bezweifle ich!
Die meisten API-Aufrufe setzen den LastError NICHT zurück.
Deshalb ist GetLastError nur dann Gültig, wenn der API-Aufruf 'Fehlgeschlagen' ist!
Ansonsten steht da ein Error-Code von einem anderen API-Aufruf drinnen, welcher irgendwan vorher stattgefunden hat.
Somit auch FehlerCodes, welche seitens deines eigendlichen Aufrufes garnicht möglich sind..
(Ich spreche da aus Erfahrung )
Angehängt ist ein Testprogramm, welches bei mir unter Win7 Prof 64Bit wie auch unter Win8.1 HOME 64Bit die SMART-Werte der Laufwerke zurück gibt.
Einloggen, um Attachments anzusehen!
|
|
jaenicke
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 09.06.17 08:15
Auch in dem Testprogramm produziert das (logischerweise) falsche Werte. Original:
Zitat: | [#] Laufwerk C (Festplatte)
HandleError = 0
SmartVersionError = 1117
SmartDataError = 1117
[#] Laufwerk D (Festplatte)
HandleError = 0
SmartVersionError = 1117
SmartDataError = 1117
[#] Laufwerk E
HandleError = 0
SmartVersionError = 1
SmartDataError = 1
[#] Laufwerk O (Festplatte)
HandleError = 0
SmartVersionError = 1117
SmartDataError = 1117
[#] Laufwerk U (Festplatte)
HandleError = 0
SmartVersionError = 5
SmartDataError = 5
[#] Laufwerk V (Festplatte)
HandleError = 0
SmartVersionError = 5
SmartDataError = 5
[#] Laufwerk W (Festplatte)
HandleError = 0
SmartVersionError = 5
SmartDataError = 5
[#] Laufwerk X (Festplatte)
HandleError = 0
SmartVersionError = 5
SmartDataError = 5
[#] Laufwerk Y (Festplatte)
HandleError = 0
SmartVersionError = 5
SmartDataError = 5
|
Nach der Korrektur (0 zurückliefern, wenn Rückgabewert True war):
Zitat: | [#] Laufwerk C (Festplatte)
HandleError = 0
SmartVersionError = 1117
SmartDataError = 1117
[#] Laufwerk D (Festplatte)
HandleError = 0
SmartVersionError = 1117
SmartDataError = 1117
[#] Laufwerk E
HandleError = 0
SmartVersionError = 1
SmartDataError = 1
[#] Laufwerk O (Festplatte)
HandleError = 0
SmartVersionError = 1117
SmartDataError = 1117
[#] Laufwerk U (Festplatte)
HandleError = 0
SmartVersionError = 0
SmartDataError = 0
[#] Laufwerk V (Festplatte)
HandleError = 0
SmartVersionError = 0
SmartDataError = 0
[#] Laufwerk W (Festplatte)
HandleError = 0
SmartVersionError = 0
SmartDataError = 0
[#] Laufwerk X (Festplatte)
HandleError = 0
SmartVersionError = 0
SmartDataError = 0
[#] Laufwerk Y (Festplatte)
HandleError = 0
SmartVersionError = 0
SmartDataError = 0
|
Es sind alles lokale Laufwerke, C, D und O sind auf einer SSD, E ist ein DVD-Brenner, U und V eine ältere SSD und die anderen liegen auf einer Festplatte.
Interessanterweise geht es mit einer der beiden SSDs.
// EDIT:
Holgerx hat folgendes geschrieben : | Angehängt ist ein Testprogramm, welches bei mir unter Win7 Prof 64Bit wie auch unter Win8.1 HOME 64Bit die SMART-Werte der Laufwerke zurück gibt. |
Das funktioniert bei mir für die Festplatte, bei der SSD wird nichts angezeigt.
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 09.06.17 08:29
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
jaenicke
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 09.06.17 08:50
Frühlingsrolle hat folgendes geschrieben : | Ich weiss nicht was ihr habt, aber in der Doku zu DeviceIoControl() steht |
Eben drum, du machst es nicht wie es dort steht.
Frühlingsrolle hat folgendes geschrieben : | MSDN hat folgendes geschrieben: | Return value
If the operation completes successfully, the return value is nonzero.
If the operation fails or is pending, the return value is zero. To get extended error information, call GetLastError. |
|
Dort steht, dass die Unterscheidung, ob die Funktion erfolgreich war, am Rückgabewert hängt (eigentlich auch logisch), und im Fehlerfall GetLastError benutzt werden kann um Details zu bekommen. Du benutzt GetLastError aber als Indikator, ob die Funktion erfolgreich war. Und das funktioniert nicht, weder laut Doku noch (siehe meine Ergebnisse) in der Realität.
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 09.06.17 10:26
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
jaenicke
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 09.06.17 10:44
Frühlingsrolle hat folgendes geschrieben : | Ich habs dann falsch verstanden. So wie es geschrieben steht heißt es: |
Da hast du aber die Absätze weggelassen. Die trennen das ganze ja schon einmal. Und dazu kommt, dass man ja nur für Fehlerinformation GetLastError nutzen soll und für nix anderes.
Egal, das gilt ja für die ganze API, jetzt weißt du es ja.
Frühlingsrolle hat folgendes geschrieben : | ... anders als beim CrystalDiskInfo: |
Dann setze doch einfach mal einen Haltepunkt auf DeviceIoControl und schaue was das Tool da so alles aufruft...
Jedenfalls keine der hier bisher genannten Funktionen... wenn ich das so sehe, greift das Ding direkt auf die ATA Schnittstelle zu, es wird nur genutzt:
IOCTL_DISK_GET_DRIVE_GEOMETRY, IOCTL_SCSI_MINIPORT, IOCTL_ATA_PASS_THROUGH, IOCTL_STORAGE_QUERY_PROPERTY, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
Ein Blick in den Quelltext lohnt dann wohl doch.
Einloggen, um Attachments anzusehen!
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 09.06.17 11:16
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
t.roller
Beiträge: 118
Erhaltene Danke: 34
|
Verfasst: Sa 10.06.17 20:31
Hier gefunden:
www.delphipraxis.net...ntraeger-wmi_sql.zip
CIMV2 - CIM_MediaAccessDevice
Win32_DiskDrive - Capabilities - CapabilityDescriptions
Ausgabe (teilweise):
instance of Win32_DiskDrive
{BytesPerSector = 512;
Capabilities = {3, 4, 10}; // 10 = SMART Notification
CapabilityDescriptions = {"Random Access", "Supports Writing", " SMART Notification"};
Das geht auch im CMD-Fenster (Als Administrator ausführen) :
wmic diskdrive get capabilities, capabilitydescriptions, caption, status
Ausgabe-Beispiel:
Capabilities CapabilityDescriptions Caption Status
{3, 4} {"Random Access", "Supports Writing"} LogiLink SCSI Disk Device OK
{3, 4, 10} {"Random Access", "Supports Writing", "SMART Notification"} ST2000LM003 HN-M201RAD OK
Einloggen, um Attachments anzusehen!
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: So 11.06.17 09:07
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
t.roller
Beiträge: 118
Erhaltene Danke: 34
|
Verfasst: So 11.06.17 11:00
Andere Version (ohne WbemScripting_TLB)
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84:
| uses ...Winapi.ActiveX, System.Win.ComObj, ...
procedure MM(s:string); begin Form1.Memo1.Lines.Add(s); end;
function VarToInt(const AVariant: Variant): integer; begin Result := StrToIntDef(Trim(VarToStr(AVariant)), 0); end;
procedure GetCIM_MediaAccessDeviceInfo; const WbemUser =''; WbemPassword =''; WbemComputer ='localhost'; wbemFlagForwardOnly = $00000020; var FSWbemLocator : OLEVariant; FWMIService : OLEVariant; FWbemObjectSet: OLEVariant; FWbemObject : OLEVariant; oEnum : IEnumvariant; iValue : LongWord; I : Integer; Data : array of WORD; params: OleVariant; begin; FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword); FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM CIM_MediaAccessDevice','WQL',wbemFlagForwardOnly); oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant; while oEnum.Next(1, FWbemObject, iValue) = 0 do begin MM(Format('Availability %d',[VartoInt(FWbemObject.Availability)])); if not VarIsNull(FWbemObject.Capabilities) then begin Data := FWbemObject.Capabilities; for I:= VarArrayLowBound(data,1) to VarArrayHighBound(data,1) do MM('Capabilities: '+IntToStr(Data[I])); end;
if not VarIsNull(FWbemObject.CapabilityDescriptions) then begin Params := FWbemObject.CapabilityDescriptions; for I:= VarArrayLowBound(Params,1) to VarArrayHighBound(Params,1) do MM('CapabilityDescriptions: '+ VarToStr(Params[I])); end;
MM(Format('Caption %s',[VartoStr(FWbemObject.Caption)])); MM(Format('CompressionMethod %s',[VartoStr(FWbemObject.CompressionMethod)])); MM(Format('ConfigManagerErrorCode %d',[VartoInt(FWbemObject.ConfigManagerErrorCode)])); MM(Format('ConfigManagerUserConfig %s',[VartoStr(FWbemObject.ConfigManagerUserConfig)])); MM(Format('CreationClassName %s',[VartoStr(FWbemObject.CreationClassName)])); MM(Format('DefaultBlockSize %d',[VartoInt(FWbemObject.DefaultBlockSize)])); MM(Format('Description %s',[VartoStr(FWbemObject.Description)])); MM(Format('DeviceID %s',[VartoStr(FWbemObject.DeviceID)])); MM(Format('ErrorCleared %s',[VartoStr(FWbemObject.ErrorCleared)])); MM(Format('ErrorDescription %s',[VartoStr(FWbemObject.ErrorDescription)])); MM(Format('ErrorMethodology %s',[VartoStr(FWbemObject.ErrorMethodology)])); MM(Format('InstallDate %s',[VartoStr(FWbemObject.InstallDate)])); MM(Format('LastErrorCode %d',[VartoInt(FWbemObject.LastErrorCode)])); MM(Format('MaxBlockSize %d',[VartoInt(FWbemObject.MaxBlockSize)])); MM(Format('MaxMediaSize %d',[VartoInt(FWbemObject.MaxMediaSize)])); MM(Format('MinBlockSize %d',[VartoInt(FWbemObject.MinBlockSize)])); MM(Format('Name %s',[VartoStr(FWbemObject.Name)])); MM(Format('NeedsCleaning %s',[VartoStr(FWbemObject.NeedsCleaning)])); MM(Format('NumberOfMediaSupported %d',[VartoInt(FWbemObject.NumberOfMediaSupported)])); MM(Format('PNPDeviceID %s',[VartoStr(FWbemObject.PNPDeviceID)])); if not VarIsNull(FWbemObject.PowerManagementCapabilities) then begin Data := FWbemObject.PowerManagementCapabilities; for I:= VarArrayLowBound(data,1) to VarArrayHighBound(data,1) do MM('PowerManagementCapabilities: '+IntToStr(Data[I])); end; MM(Format('PowerManagementSupported %s',[VartoStr(FWbemObject.PowerManagementSupported)])); MM(Format('Status %s',[VartoStr(FWbemObject.Status)])); MM(Format('StatusInfo %d',[VartoInt(FWbemObject.StatusInfo)])); MM(Format('SystemCreationClassName %s',[VartoStr(FWbemObject.SystemCreationClassName)])); MM(Format('SystemName %s',[VartoStr(FWbemObject.SystemName)])); MM('---------------------------------------------------------------------'); FWbemObject:=Unassigned; end; end; |
Ausgabe (teilweise):
Availability 0
Capabilities: 3
Capabilities: 4
Capabilities: 10
CapabilityDescriptions: Random Access
CapabilityDescriptions: Supports Writing
CapabilityDescriptions: SMART Notification
Caption ST2000LM003 HN-M201RAD
CompressionMethod
ConfigManagerErrorCode 0
ConfigManagerUserConfig False
CreationClassName Win32_DiskDrive
DefaultBlockSize 0
Description Laufwerk
DeviceID \\.\PHYSICALDRIVE0
---------------------------------------------------
Availability 0
Capabilities: 3
Capabilities: 4
CapabilityDescriptions: Random Access
CapabilityDescriptions: Supports Writing
Caption Intenso External USB 3.0 SCSI Disk Device
CompressionMethod
ConfigManagerErrorCode 0
ConfigManagerUserConfig False
CreationClassName Win32_DiskDrive
DefaultBlockSize 0
Description Laufwerk
DeviceID \\.\PHYSICALDRIVE1
|
|
|