Autor Beitrag
Frühlingsrolle
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2279
Erhaltene Danke: 419

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Fr 02.06.17 10:36 
Hallo Forum

Problemstellung:
Ich versuche herauszufinden, ob ein bestimmtes Laufwerk/(externe) Festplatte S.M.A.R.T unterstützt, um im gegebenen Fall bestimmte Informationen auszulesen.
Das Handle ist soweit gültig, die mitgegebenen Werte sollten laut Doku in Ordnung sein, dennoch liefert die Funktion jedes Mal false.
Die Frage ist nicht (nur) warum, sondern sind die structs/records (TSendCmdInParams, TSendCmdOutParams) bei mir auch richtig nachgebaut?

ausblenden volle Höhe 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:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
//Aufruf 
if SmartExists('C'then
  ShowMessage('Exist'else
  ShowMessage('Not Exist');
// ...

const
  SMART_SEND_DRIVE_COMMAND     = $0007C084;
  ENABLE_SMART                 = $000000D8;
  SMART_CYL_LOW                = $0000004F;
  SMART_CYL_HI                 = $000000C2;
  SMART_CMD                    = $000000B0;
  DRIVE_HEAD_REG               = $000000A0;

function SmartExists(ADriveLetter: Char): Boolean;
var
  root: PChar;
  hnd: THandle;
  cmdIn: TSendCmdInParams;
  cmdOut: TSendCmdOutParams;
  bytesReturned: DWord;
begin
  result := false;
  root := PChar('\\.\' + UpCase(ADriveLetter) + ':');
  hnd := CreateFile(root, GENERIC_READ or GENERIC_WRITE,
                    FILE_SHARE_READ or FILE_SHARE_WRITE, nil,
                    OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);

  if hnd <> INVALID_HANDLE_VALUE then
  begin
    cmdIn.cBufferSize := 0;
    with cmdIn.irDriveRegs do
    begin
      bFeaturesReg := ENABLE_SMART;
      bSectorCountReg := 1;
      bSectorNumberReg := 1;
      bCylLowReg := SMART_CYL_LOW;
      bCylHighReg := SMART_CYL_HI;
      bDriveHeadReg := DRIVE_HEAD_REG;
      bCommandReg := SMART_CMD;
    
      result := DeviceIoControl(hnd, SMART_SEND_DRIVE_COMMAND,
                                @cmdIn, SizeOf(cmdIn), @cmdOut, SizeOf(cmdOut),
                                bytesReturned, nil);
    end;
  end;
end;

Siehe:
- SENDCMDINPARAMS (structure)
- SENDCMDOUTPARAMS (structure)

ausblenden volle Höhe 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:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
  PIdRegs = ^TIdeRegs;
  _IDEREGS = record
    bFeaturesReg, bSectorCountReg, bSectorNumberReg, bCylLowReg,
    bCylHighReg, bDriveHeadReg, bCommandReg, bReserved: Byte;
  end;
  TIdeRegs = _IDEREGS;
  IDEREGS  = _IDEREGS;

  PDriverStatus = ^TDriverStatus;
  _DRIVERSTATUS = record
    bDriverError: Byte;
    bIDEError: Byte;
    bReserved: array[0..1of Byte;
    dwReserved: array[0..1of DWord;
  end;
  TDriverStatus = _DRIVERSTATUS;
  DRIVERSTATUS  = _DRIVERSTATUS;

  PSendCmdInParams = ^TSendCmdInParams;
  _SENDCMDINPARAMS = record
    cBufferSize: DWord;
    irDriveRegs: TIdeRegs;
    bDriveNumber: Byte;  // Don't use! System ignores it because drive handle!
    bReserved: array[0..2of Byte;
    dwReserved: array[0..3of DWord;
    bBuffer: array[0..0of Byte;
  end;
  TSendCmdInParams = _SENDCMDINPARAMS;
  SENDCMDINPARAMS  = _SENDCMDINPARAMS;

  PSendCmdOutParams = ^TSendCmdOutParams;
  _SENDCMDOUTPARAMS = record
    cBufferSize: DWord;
    DriverStatus: TDriverStatus;
    bBuffer: array[0..0of Byte;
  end;
  TSendCmdOutParams = _SENDCMDOUTPARAMS;
  SENDCMDOUTPARAMS  = _SENDCMDOUTPARAMS;


Danke für's Mitdenken!

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18694
Erhaltene Danke: 1620

W10 x64 (Chrome, IE11)
Delphi 10.2 Ent, Oxygene, C# (VS 2015), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 02.06.17 23:37 
Bei mir funktioniert die Funktion korrekt. Du musst diese allerdings mit Adminrechten ausführen.

Für diesen Beitrag haben gedankt: Frühlingsrolle
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2279
Erhaltene Danke: 419

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Sa 03.06.17 00:45 
Danke für die Rückmeldung! Hast du ansonsten etwas inhaltlich verändert, oder sind die Konstanten bei dir (anders) vordefiniert? Ich bekomm' nur false zurückgeliefert, mit oder ohne Adminrechte. Die Anwendung CrystalDiskInfo sagt mir, dass die Laufwerke SMART unterstützen. :nixweiss:

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18694
Erhaltene Danke: 1620

W10 x64 (Chrome, IE11)
Delphi 10.2 Ent, Oxygene, C# (VS 2015), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 03.06.17 08:33 
Hast du Delphi 10.1 benutzt? Ich Delphi 10.2, da sollte kein Unterschied liegen...
Und ich habe den Code 1:1 kopiert.

Hast du einmal mit Adminrechten debuggt? Bekommst du ein Handle von CreateFile?
t.roller
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 118
Erhaltene Danke: 34



BeitragVerfasst: Sa 03.06.17 10:34 
CrystalDiskInfo zeigt bei manchen USB-Drives S.M.A.R.T.-Werte an, bei manchen nicht.

Der Code vom TE scheint aber bei USB-Drives nie richtig zu funktionieren.
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2279
Erhaltene Danke: 419

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Sa 03.06.17 12:58 
Habe es nun auch mit Delphi 10.1 getestet und es lief genauso erfolglos ab. Das Handle scheint gültig zu sein. Ich hab's sicherheitshalber in 2 Methoden aufgespalten, um ganz sicher zu gehen. Es wird immer nur "Not Exist" ausgegeben:

ausblenden volle Höhe 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:
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:
function SmartExists(AHandle: THandle): Boolean; overload;
var
  cmdIn: TSendCmdInParams;
  cmdOut: TSendCmdOutParams;
  bytesReturned: DWord;
begin
  result := false;
  cmdIn.cBufferSize := 0;
  with cmdIn.irDriveRegs do
  begin
    bFeaturesReg := ENABLE_SMART;
    bSectorCountReg := 1;
    bSectorNumberReg := 1;
    bCylLowReg := SMART_CYL_LOW;
    bCylHighReg := SMART_CYL_HI;
    bDriveHeadReg := DRIVE_HEAD_REG;
    bCommandReg := SMART_CMD;
  end;
  result := DeviceIoControl(AHandle, SMART_SEND_DRIVE_COMMAND,
                            @cmdIn, SizeOf(cmdIn), @cmdOut, SizeOf(cmdOut),
                            bytesReturned, nil);
end;

function SmartExists(ADriveLetter: Char): Boolean; overload;
var
  b: Boolean;
  root: PChar;
  hnd: THandle;
begin
  b := false;
  root := PChar('\\.\' + UpCase(ADriveLetter) + ':');
  hnd := CreateFile(root, GENERIC_READ or GENERIC_WRITE,
                    FILE_SHARE_READ or FILE_SHARE_WRITE, nil,
                    OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
  if hnd = INVALID_HANDLE_VALUE then
    // zum testen
    ShowMessage('Invalid handle'else
  begin
    b := SmartExists(hnd);
    CloseHandle(hnd);
  end;
  result := b;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  if SmartExists(Edit1.Text[1]) then
    ShowMessage('Exist'else
    ShowMessage('Not Exist');  
end;


Nachtrag

An Delphi selbst sollte es nicht liegen, ob ich nun als Admin debugge oder die .EXE als Admin ausführe. Getestet habe ich es nun auch mit VC++:

ausblenden volle Höhe C++ 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:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
#include <Windows.h>

bool SmartExists(HANDLE aHandle)
{
  const int DRIVE_HEAD_REG = 0xA0;

  SENDCMDINPARAMS cmdIn;
  SENDCMDOUTPARAMS cmdOut;
  DWORD bytesReturned;

  cmdIn.cBufferSize = 0;
  cmdIn.irDriveRegs.bFeaturesReg=ENABLE_SMART;
  cmdIn.irDriveRegs.bSectorCountReg = 1;
  cmdIn.irDriveRegs.bSectorNumberReg = 1;
  cmdIn.irDriveRegs.bCylLowReg = SMART_CYL_LOW;
  cmdIn.irDriveRegs.bCylHighReg = SMART_CYL_HI;
  cmdIn.irDriveRegs.bDriveHeadReg = DRIVE_HEAD_REG;
  cmdIn.irDriveRegs.bCommandReg = SMART_CMD;

  return DeviceIoControl(aHandle, SMART_SEND_DRIVE_COMMAND, &cmdIn, sizeof(cmdIn), 
                       &cmdOut, sizeof(cmdOut), &bytesReturned, NULL);
}

int _tmain(int argc, _TCHAR* argv[])
{
  bool b = false;
  LPCWSTR root = L"\\\\.\\C:";
  HANDLE hnd = CreateFile(root, GENERIC_READ | GENERIC_WRITE,
                            FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                            OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);

  if (hnd == INVALID_HANDLE_VALUE)
    printf("Invalid handle\n");
  else
  {
    if (SmartExists(hnd))
      printf("Exist\n");
    else
      printf("Not Exist\n");
    CloseHandle(hnd);
  }

  return 0;
}

Es führt ebenso zu einem negativen Ergebnis (= Not Exist). Dann ist mein Ansatz falsch.

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18694
Erhaltene Danke: 1620

W10 x64 (Chrome, IE11)
Delphi 10.2 Ent, Oxygene, C# (VS 2015), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 03.06.17 15:03 
user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Habe es nun auch mit Delphi 10.1 getestet und es lief genauso erfolglos ab. Das Handle scheint gültig zu sein.
Was heißt scheint... Hast du das im Debugger geprüft und immer auch SysErrorMessage(GetLastError) in Strg + F7 ausgewertet?
Dann müsstest du doch ganz genau wissen was passiert... Ein Aufsplitten der Methoden brauchst du doch gar nicht.

Ich habe natürlich jetzt nur unter Windows 10 getestet, nicht unter alten Systemen.
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2279
Erhaltene Danke: 419

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Sa 03.06.17 15:42 
Den GetLastError() habe ich mir im Click-Ereignis ausgeben lassen. Da sagte er mir: "Der Vorgang wurde erfolgreich beendet". In der überladenenen (zweiten) SmartExists() Methode, sagt er: "Die Befehlslänge ist falsch":
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
function SmartExists(ADriveLetter: Char): Boolean; overload;
begin
  // ...
  begin
    b := SmartExists(hnd); // <--
    CloseHandle(hnd);
  end;
  result := b;
end;

// ergo schlägt DeviceIoControl fehl
function SmartExists(AHandle: THandle): Boolean; overload;
begin
  // ...
  result := DeviceIoControl(AHandle, SMART_SEND_DRIVE_COMMAND,
                            @cmdIn, SizeOf(cmdIn), @cmdOut, SizeOf(cmdOut),
                            bytesReturned, nil);
end;

Jetzt kann ich nur durchprobieren, welcher von mir erstellter Typ "falsch" ist bzw. auf welche Länge die Arrays für deren Buffer gebracht werden müssen.

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18694
Erhaltene Danke: 1620

W10 x64 (Chrome, IE11)
Delphi 10.2 Ent, Oxygene, C# (VS 2015), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 03.06.17 22:28 
Du kannst ja die Werte einmal im Debugger bzw. im API Monitor vergleichen...
DebugSmartCheck
DeviceIOControlCall
Einloggen, um Attachments anzusehen!

Für diesen Beitrag haben gedankt: Frühlingsrolle
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2279
Erhaltene Danke: 419

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Sa 03.06.17 23:53 
Die Starter Version zeigt im Fenster "Lokale Variablen" absolut nichts. Dafür musste ich auf D2006 ausweichen und habe im cmdOut.DriverStatus.bDriveError = 3. Mal schauen ob ich eine Auflistung der Fehlerwerte irgendwo her bekomme.
Das API Monitoring Tool ist toll. Habe ich mir gleich hier runtergeladen.

Frage: Haben t_roller und du es unter Win10 32bit getestet? Dieses Problem habe ich mittlerweile nur auf Win7 64bit.

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18694
Erhaltene Danke: 1620

W10 x64 (Chrome, IE11)
Delphi 10.2 Ent, Oxygene, C# (VS 2015), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 04.06.17 19:53 
Ich benutze nur Windows 10 64 Bit.

Leider habe ich keinen physischen PC mit einem anderen Betriebssystem mehr zur Verfügung aktuell... und in einer VM geht SMART nicht.

Die Befehlslänge ist falsch müsste ja eigentlich heißen, dass die Strukturgröße falsch ist. Ist die denn identisch zu mir (36 bzw. 20)?
t.roller
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 118
Erhaltene Danke: 34



BeitragVerfasst: So 04.06.17 22:50 
Hier ist eine Liste von smartmontools, die USB-Bridges und HDDs enthält.
www.smartmontools.or...upported_USB-Devices

Wenn smartmontools und CrystalDiskInfo nicht funktionieren, werden DELPHI-Programme auch nicht funktionieren.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18694
Erhaltene Danke: 1620

W10 x64 (Chrome, IE11)
Delphi 10.2 Ent, Oxygene, C# (VS 2015), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 04.06.17 22:57 
user profile icont.roller hat folgendes geschrieben Zum zitierten Posting springen:
Wenn smartmontools und CrystalDiskInfo nicht funktionieren, werden DELPHI-Programme auch nicht funktionieren.
Das Problem ist ja offenbar, dass der Aufruf fehlschlägt. Dass es prinzipiell mit der Festplatte geht, hat er ja auch schon geschrieben:
user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Die Anwendung CrystalDiskInfo sagt mir, dass die Laufwerke SMART unterstützen. :nixweiss:
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2279
Erhaltene Danke: 419

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Mo 05.06.17 00:30 
user profile iconjaenicke hat folgendes geschrieben:
Die Befehlslänge ist falsch müsste ja eigentlich heißen, dass die Strukturgröße falsch ist. Ist die denn identisch zu mir (36 bzw. 20)?

Das heißt es! Den Fehler bekomm ich oft genug, wenn ich mit Devices zu tun habe, wie hier.

Die Werte sind wie bei dir 36 (bufferSizeIN), 20 (bufferSizeOUT).

Folgendes unterscheidet sich zu deinen Messwerten: bytesReturned bleibt bei 0 (vorher, nachher), weil cmdOut.DriverStatus.bDriveError = 3 (ungültiges Device) liefert und cmdIn.bDriveNumber den Wert 176 zugwiesen bekommt.
Der Wert ist viel zu groß. Das Handle ist aber gültig.

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18694
Erhaltene Danke: 1620

W10 x64 (Chrome, IE11)
Delphi 10.2 Ent, Oxygene, C# (VS 2015), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 05.06.17 06:23 
user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
cmdIn.bDriveNumber den Wert 176 zugwiesen bekommt
Du solltest den Inhalt des Records einmal mit 0 initialisieren. bDriveNumber wird zwar laut Doku ignoriert, aber vielleicht stören ja andere nicht initialisierte Werte...
Denn da stehen ja dann "zufällige" Werte drin.

Vielleicht so?
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
//...
  if hnd <> INVALID_HANDLE_VALUE then
  begin
    ZeroMemory(@cmdIn, SizeOf(cmdIn));
    with cmdIn.irDriveRegs do
    begin
      bFeaturesReg := ENABLE_SMART;
      bSectorCountReg := 1;
      bSectorNumberReg := 1;
      bCylLowReg := SMART_CYL_LOW;
      bCylHighReg := SMART_CYL_HI;
      bDriveHeadReg := DRIVE_HEAD_REG;
      bCommandReg := SMART_CMD;

      ZeroMemory(@cmdOut, SizeOf(cmdOut));
      result := DeviceIoControl(hnd, SMART_SEND_DRIVE_COMMAND,
                                @cmdIn, SizeOf(cmdIn), @cmdOut, SizeOf(cmdOut),
                                bytesReturned, nil);
    end;
  end;
//...

// EDIT:
Und dann steht da in der Doku noch das...
msdn.microsoft.com/e...566206(v=vs.85).aspx hat folgendes geschrieben:
If SMART status is being requested, the output buffer must be >= (sizeof(SENDCMDOUTPARAMS) - 1 + sizeof(IDEREGS)).

Vielleicht funktioniert das erst ab Windows 10 auch ohne diesen Bufferteil...
Füge doch einfach mal diese IdeRegs noch in die OutParams ein:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
  _SENDCMDOUTPARAMS = record
    cBufferSize: DWord;
    DriverStatus: TDriverStatus;
    bBuffer: array[0..0of Byte;
    irDriveRegs: TIdeRegs;
  end;
Übergebe ich als Größe der Out-Params aber zu wenig, bekomme ich den Fehler:
Zitat:
Der an einen Systemaufruf übergebene Datenbereich ist zu klein
Deshalb vermute ich nicht, dass es daran liegt.

// EDIT2:
Ich habe gerade gelesen, dass nicht alle Mainboards mit nForce Chipsatz diese SMART Kommandos unterstützen. Hast du zufällig so eins?

// EDIT3:
Bist du sicher, dass du für die Abfrage des SMART Status den richtigen Befehl benutzt? Ich verstehe deinen Befehl so, dass du SMART damit versuchst zu aktivieren...
Sollte nicht eher SMART_RCV_DRIVE_DATA dafür geeignet sein?
ausblenden volle Höhe 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:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
const
  SMART_SEND_DRIVE_COMMAND     = $0007C084;
  ENABLE_SMART                 = $000000D8;
  SMART_CYL_LOW                = $0000004F;
  SMART_CYL_HI                 = $000000C2;
  SMART_CMD                    = $000000B0;
  DRIVE_HEAD_REG               = $000000A0;
  READ_ATTRIBUTES              = $D0;
  READ_THRESHOLDS              = $D1;

function SmartExists(ADriveLetter: Char): Boolean;
var
  root: PChar;
  hnd: THandle;
  cmdIn: TSendCmdInParams;
  cmdOut: TSendCmdOutParams;
  bytesReturned: DWord;
begin
  result := false;
  root := PChar('\\.\' + UpCase(ADriveLetter) + ':');
  hnd := CreateFile(root, GENERIC_READ or GENERIC_WRITE,
                    FILE_SHARE_READ or FILE_SHARE_WRITE, nil,
                    OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);

  if hnd <> INVALID_HANDLE_VALUE then
  begin
    ZeroMemory(@cmdIn, SizeOf(cmdIn));
    cmdIn.cBufferSize := 512;
    with cmdIn.irDriveRegs do
    begin
      bFeaturesReg := READ_ATTRIBUTES;
      bCommandReg := SMART_CMD;
      bDriveHeadReg := DRIVE_HEAD_REG;

      ZeroMemory(@cmdOut, SizeOf(cmdOut));
      result := DeviceIoControl(hnd, SMART_RCV_DRIVE_DATA,
                                @cmdIn, SizeOf(cmdIn), @cmdOut, SizeOf(cmdOut),
                                bytesReturned, nil);
    end;
  end;
end;

Für diesen Beitrag haben gedankt: Frühlingsrolle
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2279
Erhaltene Danke: 419

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Mo 05.06.17 07:41 
Gute Idee die Werte auf 0 zu setzen. Jetzt sieht man umso besser, dass nichts im cmdOut ankommt. :D Du hast mit der auszitierten Anfrage recht. Es bringt dennoch nichts. Könnte gut sein, dass auch mein Intel Chipsatz die Ausnahme von der Regel ist?!
Ne, bevor mir noch graue Haare wachsen, schau ich mir das OpenSource Projekt CrystalDiskInfo an, siehe hier. Die interessanten Stellen sind im AtaSmart.h und AtaSmart.cpp vorzufinden.

Ich danke dir für die Bereitschaft, jaenicke!!

Weil ich den 3. Edit zu spät bemerkt habe: SMART_RCV_DRIVE_DATA schnell mal getestet und da bekomm' ich den selben Fehler wie du vorhin, nämlich
Zitat:
Der an einen Systemaufruf übergebene Datenbereich ist zu klein
.

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18694
Erhaltene Danke: 1620

W10 x64 (Chrome, IE11)
Delphi 10.2 Ent, Oxygene, C# (VS 2015), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 05.06.17 08:34 
Mit SMART_RCV_DRIVE_DATA bekomme ich auch problemlos die einzelnen Werte für die Smart-Daten. Die stimmen auch mit CrystalDiskInfo überein.
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2279
Erhaltene Danke: 419

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Mo 05.06.17 08:43 
Die (digitale) Welt ist gegen mich. Da kann ich nichts machen. :rofl: Ich schau mir mal an wie CrystalDiskInfo es handhabt. Das funktioniert dort auch prima, also muss es bei mir ebenso funktionieren.
Dass mein Code generell bei mir! nicht funktioniert, zeigt sich sowohl in Delphi als auch in Visual Studio. Mal sehen. Bis demnächst :wink2:

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)
Frühlingsrolle Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2279
Erhaltene Danke: 419

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Di 06.06.17 09:26 
Da CrystalDiskInfo mir für meine externen Laufwerke und dem Systemlaufwerk (C:\) unter "Eigenschaften" SMART ausgibt, und ebenso Werte in der Tabelle auflistet, müssen die Laufwerke SMART unterstützen, oder nicht?!

Daher habe ich geschaut, ob überhaupt "SMART commands" möglich sind.
Der Befehl SMART_GET_VERSION gibt gegebenfalls im GETVERSIONINPARAMS.fCapabilities = CAP_SMART_CMD(4) bzw. "The device supports SMART commands" zurück:

ausblenden volle Höhe 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:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
const
  SMART_GET_VERSION = $74080;

type
  GETVERSIONINPARAMS = record
    bVersion, bRevision, bReserved, bIDEDeviceMap: Byte;
    fCapabilities: DWord; 
    dwReserved: array[0..3of DWord;
  end;

function SmartTest(AHandle: THandle): Boolean;
var
  bytesReturned: DWord;
  gvParams: GETVERSIONINPARAMS;
begin
  ZeroMemory(@gvParams, SizeOf(gvParams)); // nachträglich hizugefügt
  result := DeviceIoControl(AHandle, SMART_GET_VERSION, nil0,
                            @gvParams, SizeOf(gvParams), bytesReturned, nil);  // <-- gvParams.fCapabilities = 0
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  hnd: THandle;
  root: PChar;
begin
  root := PChar('\\.\T:');
  hnd := CreateFile(root, GENERIC_READ or GENERIC_WRITE,
                    FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING,
                    00);
  if hnd <> 0 then
  begin
    SmartTest(hnd);
    ShowMessage(SysErrorMessage(GetLastError)); // <-- ERROR_NOT_SUPPORTED(50):  The request is not supported. 
    CloseHandle(hnd);
  end;
end;


Frage, ist mit der Fehlermeldung gemeint, dass mein Betriebssystem dies generell nicht verarbeiten kann, oder unterstützt das Laufwerk doch kein SMART?

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)


Zuletzt bearbeitet von Frühlingsrolle am Di 06.06.17 10:01, insgesamt 1-mal bearbeitet
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18694
Erhaltene Danke: 1620

W10 x64 (Chrome, IE11)
Delphi 10.2 Ent, Oxygene, C# (VS 2015), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 06.06.17 09:43 
Du hast wieder das ZeroMemory vergessen... ;-)