Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Hardwareinfos (https://www.delphipraxis.net/5789-hardwareinfos.html)

cchris 19. Jun 2003 12:56


Hardwareinfos
 
Hallo!

Ich will für eine Registrierfunktion eines Programmes
einen Hardwareschlüssel erstellen, der auf jedem Computer
anders ist, aber möglichst von wenigen Kernkomponenten
( z.B. Prozessor / Mainboard ) abhängt, da man die ja
im Gegensatz zu Peripherie ( z.B: Drucker ) selten wechselt.
Könnt ihr mir irgendwie sagen wie man z.B. Processorseriennummer
oder Mainboardseriennummer ausliest? ( auch BIOS wär nicht schlecht ) :?:

MfG Christian

:cat:

FriFra 19. Jun 2003 13:39

Ich hab vor Jahren mal irgendwo folgende Funktionen für die CPU-ID gefunden:
Delphi-Quellcode:
const
  ID_BIT = $200000; // EFLAGS ID bit
type
  TCPUID = array[1..4] of Longint;

function IsCPUID_Available: Boolean; register;
asm
PUSHFD            {direct access to flags no possible, only via stack}
POP    EAX       {flags to EAX}
MOV    EDX,EAX   {save current flags}
XOR    EAX,ID_BIT {not ID bit}
PUSH   EAX       {onto stack}
POPFD             {from stack to flags, with not ID bit}
PUSHFD            {back to stack}
POP    EAX       {get back to EAX}
XOR    EAX,EDX   {check if ID bit affected}
JZ     @exit     {no, CPUID not availavle}
MOV    AL,True   {Result=True}
@exit:
end;

function GetCPUID: TCPUID; assembler; register;
asm
PUSH   EBX      {Save affected register}
PUSH   EDI
MOV    EDI,EAX  {@Resukt}
MOV    EAX,1
DW     $A20F    {CPUID Command}
STOSD            {CPUID[1]}
MOV    EAX,EBX
STOSD            {CPUID[2]}
MOV    EAX,ECX
STOSD            {CPUID[3]}
MOV    EAX,EDX
STOSD            {CPUID[4]}
POP    EDI      {Restore registers}
POP    EBX
end;
Ich errechne mir aus den 4 CPU-ID's eine eindeutige ID. Ich habe damit bisher sehr gute Erfahrungen gemacht.
Achtung: Es kann sein, dass eine CPU-ID negativ ist! Ich verwende diese Funktion seit ca. 1998 und hatte diese Woche zum ersten mal einen Kunden mit einem "-" innerhalb der ID, deshalb musste ich an meiner Registrierungsprocedur noch nachbessern... ich hatte einfach nicht mit negativen Werten gerechnet :oops:

Eine mögliche Implementation wäre:
Delphi-Quellcode:
function GetID: string;
//IntToPos ist notwendig, da in extrem seltenen Fällen negative CPU-ID's vorkommen
  function IntToPos(Value: Integer): integer; overload;
  begin
    if Value < 0 then
      Result := -Value
    else
      Result := Value;
  end;
  function IntToPos(Value: Int64): int64; overload;
  begin
    if Value < 0 then
      Result := -Value
    else
      Result := Value;
  end;
begin
  if IsCPUID_Available then
    result := IntToStr(IntToPos(GetCPUID[1])) + IntToStr(IntToPos(GetCPUID[2]))
      + IntToStr(IntToPos(GetCPUID[3])) + IntToStr(IntToPos(GetCPUID[4]))
  else
    result := '0123456789'; //Dummywert
end;

P.S. Dieser Beitrag gehört aber nicht in "Internet / IP / LAN"

sakura 19. Jun 2003 14:01

Zitat:

Zitat von FriFra
P.S. Dieser Beitrag gehört aber nicht in "Internet / IP / LAN"

Na dann *wuppdi*

...:cat:...

torud 12. Mär 2007 12:54

Re: Hardwareinfos
 
Auf all meinen Testumgebungen erhielt ich IMMER 2 verschiedene ID´s. Bei jedem Programmstart lies ich diese ID erstellen und verglich sie mit der in einer Ini-Datei gespeicherten und stellte dabei fest, dass auf meinem PC und meinen Laptops grundsätzlich 2 verschiedene ID´s erzeugt werden.

Ich habe es auch mal über längere Zeit mitgeloggt. Es sind tatsächlich NUR 2 ID´s, aber das macht irgendwie keinen Sinn. Hat jemand einen Erklärungsansatz!?

Nur um Fragen vorzubeugen: Die Hardware hat sich nie verändert, auch keine neuen USB-Geräte oder was auch immer. Ich konnte das Tool innerhalb von 10 Minuten 10 mal starten und konnte sicher sein, dass ich midestens 2 mal ein andere ID hatte. Ich erhielt also niemals immer die gleiche ID bei 10 Starts. Auf dem Leptop eines Kollege hingegen gibt es keinerlei Probleme. Bei ihm läufts und läufts und läufts...mit einer ID.

himitsu 12. Mär 2007 13:26

Re: Hardwareinfos
 
Hast du vielleicht mehrere CPUs/Kerne?
(Multiprozessor, DualCore oder sowas)

Dann könnte es eventuell daran liegen auf welchem Kern das Programm gerade läuft, also vorm welchem die CPUID ausgelesen wird. :gruebel:


PS: die CPUID liefert nur informationen über die CPU, also es ist egals was sonst in/an dem Rechner dran ist.

CPUID $00000001 liefert z.B.:
SerialNumber, Family, Stepping, Overdrive, PType, Model und die StandardFeatures der CPU und die CPUCount

torud 12. Mär 2007 13:35

Re: Hardwareinfos
 
Also mein HomePC ist ein "alter" Rechner mit Win98 und nem 1000er Celeron. Also was ganz einfaches und normales. Mein Laptop ist mit XP bestückt und hat ein DUAL Core-PRozessor. Der Laptop vom Kollegen wo es läuft ist ein Win2000-System mit einem einfachen alten P3.

Hilft das vielleicht weiter?

Ich bräuchte auf jeden Fall was brauchbares ab Win98 aufwärtskompatibel. Ich suche schon ne ganze Weile bei Google nach brauchbarem Code, aber es gar nicht soo einfach...

torud 12. Mär 2007 13:45

Re: Hardwareinfos
 
Das hier sind die beiden ID´s, die ich erhalte:

1768133120495451075184641
176816910336495451075184641

der unterschied ist gar nicht soo gross!

17681 33120 495451075184641
17681 6910336 495451075184641

himitsu 12. Mär 2007 14:02

Re: Hardwareinfos
 
Liste der Anhänge anzeigen (Anzahl: 2)
Dann versuch es mal hiermit und teile uns dann mit was sich geändert hat:
Delphi-Quellcode:
Function GetID: String;
  Var ID: TCPUID;

  Begin
    If IsCPUID_Available Then Begin
      ID := GetCPUID;
      Result := Format('%.8x %.8x %.8x %.8x', [ID[1], ID[2], ID[3], ID[4]]);
    End Else Result := '[error]';
  End;
Alternativ könntest du ach mal direkt nachsehn, was sich genau ändert.
Programm+Bild im Anhang > speziell darauf achten wo ich was rosa markiert hab.

[edit]
:lol: dabei wollt ich grad nach den Werten fragen.

*mit umrechnen anfang* mal sehn was sich findet :angel:

[add]
ich hoffe mal du hast genau zwischen den ID-Werten aufgetrennt und das sich Ändernte soll den 2. Wert darstellen :stupid:

[add2]
OK, entweder hast du nicht an der Grenze aufgetrennt, oder ich rechne falsch :gruebel: ,denn
CPUID $00000001 EBX besagt
Code:
33120    00[color=#ff0000]00[/color]8160 =  0 CPUs
6910336  00[color=#ff0000]69[/color]7180 = 105 CPUs

torud 12. Mär 2007 14:10

Re: Hardwareinfos
 
Tolles tool. Ok, bevor ich die Screens zu meinen Ausführungen hochlade, hier meine Infos.

Tool gestartet.

Bin auf Seite 1.

Inhalt der GUID to String ändert sich jede Sekunde im Edit!!! (soll das so sein???)
Inhalt des Memos ändert sich nicht
GetBootTime ist alles korrekt mit laufender Uhr
Number of processors ist korrekt (2)

auf Seite 2 ist nichts auffälliges.

////////////////////////////////////////////////////////////

Mit Deinem neuen Code erhalte ich diese beiden ID´s

000006E8 00020800 0000C189 BFE9FBFF
000006E8 01020800 0000C189 BFE9FBFF

himitsu 12. Mär 2007 14:20

Re: Hardwareinfos
 
Ja, die GUID soll, oder besser muß sich ändern, es wird schließlich sekündlich 'ne Neue von Windows angefordert ... ist ein Testprogamm einer meiner Units (halt die mit den ganzen "System"-Funktionen) ;)

OK, ich hab richtig gerechnet und du hattest eben nicht an den Registergrenzen getrennt *erleichtert bin*


So, dann hier mal die korregierte Funktion :angel:
in EBX ist meines Erachtens nur das 3. Byte definiert (CPUCount) und der Rest kann variieren.
Delphi-Quellcode:
function GetID: string;
  function IntToPos(Value: Integer): integer;
  begin
    if Value < 0 then
      Result := -Value
    else
      Result := Value;
  end;
var ID: TCPUID;
begin
  if IsCPUID_Available then
  begin
    ID := GetCPUID;
    result := IntToStr(IntToPos(ID[1])) + IntToStr(IntToPos((ID[2] shr 16) and $FF))
      + IntToStr(IntToPos(ID[3])) + IntToStr(IntToPos(ID[4]));
  end
  else
    result := '0123456789'; //Dummywert
end;
[add]
Ach übrigens, statt IntToPos kann man auch Abs verwenden :angel2:

Delphi-Quellcode:
Unit Math;

function GetID: string;
var ID: TCPUID;
begin
  if IsCPUID_Available then
  begin
    ID := GetCPUID;
    result := IntToStr(Abs(ID[1])) + IntToStr(Abs((ID[2] shr 16) and $FF))
      + IntToStr(Abs(ID[3])) + IntToStr(Abs(ID[4]));
  end
  else
    result := '0123456789'; //Dummywert
end;
[add2]
Ach, da es mir grad so schön Spaß macht :lol: , hier nocheine Version, welche wohl besser sein sollte, da hier die Vorzeichenbits nicht ignoriert werden.

Die ersten beiden Funktionen liefern das selbe Erbebnis, aber hier kommt natürlich eventuell was anderes raus, halt wegen der beachteten Vorzeichenbits.

Delphi-Quellcode:
function GetID: string;
var ID: TCPUID;
begin
  if IsCPUID_Available then
  begin
    ID := GetCPUID;
    result := Format('%d%d%d%d', [ID[1], (ID[2] shr 16) and $FF, ID[3], ID[4]]);
  end
  else
    result := '0123456789'; //Dummywert
end;
[nachtrag]
und zu dem ID:=GetCPUID;
ich glaub da sollte auffallen, daß es schließlich reicht, wenn nur einmal die Werte von der CPU abgefragt werden und nicht gleich viermal.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:43 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz