About the hard disk serial number, motherboard information, CPU ID, from the big rich to the list:
First, get the hard disk serial number: (lost, apologize to the author!)
/ / Hard disk serial number acquisition
Function gethdnum: pchar; stdcall;
Type tsrbiocontrol = packed record
HeaderLength: ulong;
Signature: array [0..7] of char;
Timeout: ulong;
Controlcode: Ulong;
Returncode: ulong;
Length: ulong;
END;
SRB_IO_CONTROL = Tsrbiocontrol;
Psrbiocontrol = ^ Tsrbiocontrol;
TIDEREGS = PACKED RECORD
BfeatureSreg: Byte; // subsid for specifying smart "commands".
Bsectorcountreg: Byte; // Ide Sector Count Register
Bsectornumberreg: Byte; // Ide Sector Number Register
BcyllowReg: Byte; // Ide Low Order Cylinder Value
Bcylhighreg: byte; // ide High Order Cylinder Value
BDRIVEHEADREG: BYTE; // Ide Drive / Head Register
BCOMMANDREG: BYTE; / / ACTUAL IDE Command.
BRESERVED: BYTE; // RESERVED. Must be Zero.
END;
Ideregs = TIDEREGS;
PideRegs = ^ TIDEREGS;
Tsendcmdinparams = Packed Record
CBuffersize: DWORD;
IrDriveRegs: TIDEREGS;
BDRIVENUMBER: BYTE;
BRESERVED: ARRAY [0..2] of byte;
DWRESERVED: ARRAY [0..3] of dword;
BBuffer: array [0..0] of byte;
END;
Sendcmdinparams = tsendcmdinparams;
Psendcmdinparams = ^ tsendcmdinparams;
TIDSECTOR = Packed Record
Wgenconfig: Word;
WORCYLS: WORD;
WRESERVED: WORD;
WREMHEADS: WORD;
WbytesperTrack: Word;
Wbytespersector: Word;
Wsectorspertrack: Word;
Wvendorunique: array [0..2] of word;
sSerialnumber: array [0..19] of char;
WBuffertype: Word;
WBuffersize: Word;
Weccsize: word;
Sfirmwarerev: array [0..7] of char;
Smodelnumber: array [0..39] of char;
WMOREVENDORUNIQUE: WORD;
WDOUBLEWORDIO: WORD;
WCAPABILITIES: WORD;
WRESERVED1: WORD;
WPIOTIMING: WORD;
WDMATIMING: WORD; WORD;
WNUMCURRENTCYLS: WORD;
WORUMCURRENTHEADS: WORD;
WNUMCURRENTSECTORSPERTRACK: WORD;
Ulcurrentsectorcapacity: ulong;
WMULTSECTORSTUFF: WORD;
UltotaladdressAplasectors: ulong;
WSINGLEWORDDMA: WORD;
WMULTIWORDDMA: WORD;
BRESERVED: ARRAY [0..127] of byte;
END;
Pidsector = ^ TIDSector;
Const
IDE_ID_Function = $ EC;
Identify_buffer_size = 512;
DFP_RECEIVE_DRIVE_DATA = $ 0007C088;
IOCTL_SCSI_MINIPORT = $ 0004d008;
IOCTL_SCSI_MINIPORT_IDENTIFY = $ 001B0501;
DataSize = SizeOf (Tsendcmdinparams) -1 Identify_buffer_size;
Buffersize = SizeOf (SRB_IO_CONTROL) DATASIZE;
W9XBUFFERSIZE = Identify_buffer_size 16;
VAR
HDEVICE: THANDLE;
CbbytesReturned: DWORD;
Pindata: psendcmdinparams;
Poutdata: Pointer; // psendcmdoutparams
Buffer: array [0..buffersize-1] of byte;
SRBControl: Tsrbiocontrol Absolute Buffer;
Procedure Changebyteorder (Var Data; Size: Integer);
VAR
PTR: PCHAR;
i: integer;
C: char;
Begin
PTR: = @data;
For i: = 0 to (Size Shr 1) -1 DO
Begin
C: = ptr ^;
PTR ^: = (PTR 1) ^;
(PTR 1) ^: = C;
INC (PTR, 2);
END;
END;
Begin
Result: = '';
Fillchar (buffer, buffersize, # 0);
IF Win32Platform = VER_PLATFORM_WIN32_NT THEN
Begin // Windows NT, Windows 2000
// Get SCSI Port Handle
HDevice: = createfile ('//./scsi0:', generic_read or generic_write,
File_share_read or file_share_write, nil, open_existing, 0, 0);
if HDevice = Invalid_Handle_Value Then
EXIT;
Try
SRBControl.HeaderLength: = SIZEOF (SRB_IO_CONTROL);
System.move ('Scsidisk', SRBControl.Signature, 8);
SRBControl.timeout: = 2;
SRBControl.Length: = DATASIZE;
SRBControl.Controlcode: = ioctl_scsi_miniport_identify; pindata: = psendcmdinparams (pchar (@Buffer) SizeOf (SRB_IO_CONTROL));
Poutdata: = pindata;
With pindata ^ do
Begin
CBuffersize: = Identify_buffer_size;
BDRIVENUMBER: = 0;
With irdriveRegs do
Begin
BFEATURESREG: = 0;
Bsectorcountreg: = 1;
Bsectornumberreg: = 1;
Bcyllowreg: = 0;
BcylhighReg: = 0;
BDRIVEHEADREG: = $ A0;
BCOMMANDREG: = IDE_ID_FUNCTION;
END;
END;
IF not DeviceioControl (HDevice, IOCTL_SCSI_MINIPORT, @Buffer, Buffear, @buffer, buffersize,
CbbytesReturned, NIL) THEN
EXIT;
Finally
CloseHandle (HDEvice);
END;
end
Else Begin // Windows 95 OSR2, Windows 98
// Win98 to be c: / windows / system / smartvsd.vxd
// Copy to C: / Windows / System / iosubsys
// reboot your computer and ok
HDevice: = Createfile ('//./smartvsd', 0, 0, nil, create_new, 0, 0);
if HDevice = Invalid_Handle_Value Then
EXIT;
Try
Pindata: = psendcmdinparams (@Buffer);
Poutdata: = @pindata ^ .bbuffer;
With pindata ^ do
Begin
CBuffersize: = Identify_buffer_size;
BDRIVENUMBER: = 0;
With irdriveRegs do
Begin
BFEATURESREG: = 0;
Bsectorcountreg: = 1;
Bsectornumberreg: = 1;
Bcyllowreg: = 0;
BcylhighReg: = 0;
BDRIVEHEADREG: = $ A0;
BCOMMANDREG: = IDE_ID_FUNCTION;
END;
END;
IF not DeviceioControl (HDevice, DFP_RECEIVE_DRIVE_DATA,
Pindata, Sizeof (Tsendcmdinparams) -1, Poutdata, W9xBuffersize, CbbytesReturned, NIL) THEN
EXIT;
Finally
CloseHandle (HDEvice);
END;
END;
WITH PIDSECTOR (Pchar (Poutdata) 16) ^ DO
Begin
Changebyteorder (SSERIALNUMBER, SIZEOF (SSERIALNUMBER);
(Pchar (@SSerialNumber) sizeof (sserialnumber) ^: = # 0;
Result: = pchar (@sserialnumber);
END;
Second, get CPUID.
/
// (c) NPS, 1997 - Idea, Realisation, Adoptation Iscpuid_available //
// kvk@estpak.ee //
// (c) Alex Abreu, 1997 - Iscpuid_available Source and IDEA //
// simonet@bhnet.com.br //
/
Interface
Uses
Windows,
Messages,
SYSUTILS,
Classes,
Graphics,
Controls,
Forms,
Dialogs,
EXTCTRLS,
STDCTRLS,
Buttons;
Type
TDemoform = Class (TFORM)
Label1: TLABEL;
Label2: TLABEL;
Label3: TLABEL;
Label4: TLABEL;
GetButton: Tbitbtn;
CloseButton: Tbitbtn;
Bevel1: TBevel;
Label5: TLABEL;
Flabel: TLABEL;
MLabel: TLABEL;
Plabel: TLABEL;
SLABEL: TLABEL;
PVALUE: TLABEL;
Fvalue: TLABEL;
Mvalue: TLABEL;
Svalue: TLABEL;
Procedure getButtonClick (Sender: TOBJECT);
END;
VAR
Demoform: TDemoform;
IMPLEMentation
{$ R * .dfm}
Const
ID_bit = $ 200000; // EFLAGS ID BIT
Type
TCPUID = array [1..4] of longint
Tvendor = array [0..11] of char;
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;
. "" "" "" "" "" "" "" "" "" "" "
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;
....................
ASM
Push ebx {save affected register}
Push EDI
Mov Edi, EAX {@Result (tvendor)}
MOV EAX, 0
DW $ A20F {cpuid command}
MOV EAX, EBX
XCHG EBX, ECX {Save ECX Result}
MOV ECX, 4
@1:
Stosb
SHR EAX, 8
LOOP @ 1
MOV EAX, EDX
MOV ECX, 4
@2:
Stosb
SHR EAX, 8
Loop @ 2
MOV EAX, EBX
MOV ECX, 4
@ 3:
Stosb
SHR EAX, 8
Loop @ 3
Pop edi {restore registers}
POP EBX
END;
Procedure TDemoform.getButtonclick (Sender: TOBJECT);
VAR
CPUID: TCPUID;
I: integer;
S: Tvendor;
Begin
For i: = low (cpuid) to high (cpuid) do cpuid [i]: = -1;
IF iscpuid_available the begin
CPUID: = getcpuid;
Label1.caption: = 'CPUID [1] =' INTTOHEX (CPUID [1], 8);
Label2.caption: = 'CPUID [2] =' INTTOHEX (CPUID [2], 8);
Label3.caption: = 'CPUID [3] =' INTTOHEX (CPUID [3], 8);
Label4.caption: = 'cpuid [4] =' INTTOHEX (CPUID [4], 8);
PVALUE.CAPTION: = INTTOSTR (CPUID [1] SHR 12 and 3);
FValue.caption: = INTTOSTR (CPUID [1] SHR 8 and $ f);
Mvalue.caption: = INTTOSTR (CPUID [1] SHR 4 and $ f);
Svalue.caption: = INTTOSTR (CPUID [1] and $ f);
S: = getcpuvendor;
Label5.caption: = 'vendor:' s; endelse begin
Label5.caption: = 'cpuid not available';
END;
END;
End.
Third, get the motherboard information and CPU ID:
ID = 1792473, posted rich: fz97530, posting time: 2003-4-22 5: 03: 00Unit mbcpuid;
Interface
Uses
Windows, Messages, Sysutils, Classes, Graphics, Controls, Forms, DSgnintf;
Type
TMBCPUID = Class (Tcomponent)
Private
Fabout: String;
FMBINFO: STRING;
FCPUID: String;
protected
{Protected Declarations}
public
{Public declarations}
Constructor Create (Aowner: Tcomponent); OVERRIDE;
Procedure loading; Override;
DESTRUCTOR DESTROY; OVERRIDE;
Procedure showabout;
Published
Property About: String Read Fabout Write Fabout Stored False;
Property Getmbinfo: String Read Fmbinfo;
Property getcpuid: string read fcpuid;
{Published Declarations}
END;
PROCEDURE register;
IMPLEMentation
Const
ID_bit = $ 200000; // EFLAGS ID BIT
Type
TCPUID = array [1..4] of longint
{Private Declarations}
Type
TaboutProperty = Class (TPropertyEditor)
public
Procedure edit; Override;
Function GetAttributes: tpropertyAttributes; Override;
Function GetValue: String; Override;
END;
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;
....................
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;
PROCEDURE register;
Begin
RegisterComponents ('Samples', [TMBCPUID]);
RegisterPropertyEditor (TypeInfo (String), TMBCPUID,
'About', TaboutProperty;
END;
Constructor TMBCPUID.CREATE (AOWNER: TComponent);
Begin
Inherited Create (Aowner);
END;
Procedure TMBCPUID.LOADED;
VAR
CPUID: TCPUID;
Mbinf: pchar;
i: integer;
Begin
Inherited loaded; {always call the inherited loaded first!}
Fabout: = 'Read the motherboard number, CPUID control, Zhang Yang production, must be a boutique;
IF iscpuid_available the cpuid: = getcpuidsn else begin
// Early CPU no ID
CPUID [1]: = 1528;
CPUID [4]: = 24682468;
END;
FCPUID: = INTTOHEX ((CPUID [1] CPUID [4]), 8);
Mbinf: = PCHAR (PTR ($ FEC71));
For i: = 11 to Length (String (mbinf)) DO
Fmbinfo: = fmbinfo mbinf [i]; // The first one is the BIOS upgrade date,
END;
DESTRUCTOR TMBCPUID.DESTROY;
Begin
Inherited destroy;
END;
Procedure Taboutproperty.EDIt;
Begin
TMBCPUID (GetComponent). Showabout;
END;
Function Taboutproperty.gettributes: tpropertyAttribute;
Begin
GetaTtributes: = [Padialog, Pareadonly];
END;
Function Taboutproperty.getValue: string;
Begin
GetValue: = '(About)';
END;
Procedure TMBCPUID.SHOWABOUT;
VAR
Msg: String;
Const
Cr = CHR (13);
Begin
Msg: = 'Read the motherboard number, CPUID control' CR 'For D4, D5, D6, CB4, CB5' Cr;
Msg: = MSG 'WIN9X / ME / NT / 2K / XP' Cr Cr; Msg: = MSG 'Copyright 2001 Moonsoft' CR 'Zhang Yang production, must be boutique!' Cr;
Msg: = msg 'e-mail: cdlock@21cn.com' Cr;
Application.MessageBox (PCHAR (MSG), 'version prompt (final version)', MB_OK;
END;
End.
The above excerpts, I have not been verified and is for reference only. . . .