unit HardwareIDGenerator;
interface
uses
System.Classes, System.SysUtils,
Winapi.ActiveX, System.Win.ComObj, System.Variants;
type
TMotherBoardInfo = (Mb_SerialNumber, Mb_Manufacturer, Mb_Product, Mb_Model);
TMotherBoardInfoSet =
set of TMotherBoardInfo;
TProcessorInfo = (Pr_Description, Pr_Manufacturer, Pr_Name, Pr_ProcessorId, Pr_UniqueId);
TProcessorInfoSet =
set of TProcessorInfo;
TBIOSInfo = (Bs_BIOSVersion, Bs_BuildNumber, Bs_Description, Bs_Manufacturer, Bs_Name, Bs_SerialNumber, Bs_Version);
TBIOSInfoSet =
set of TBIOSInfo;
TOSInfo = (Os_BuildNumber, Os_BuildType, Os_Manufacturer, Os_Name, Os_SerialNumber, Os_Version);
TOSInfoSet =
set of TOSInfo;
const // properties names to get the data
MotherBoardInfoArr:
array [TMotherBoardInfo]
of AnsiString = ('
SerialNumber', '
Manufacturer', '
Product', '
Model');
OsInfoArr:
array [TOSInfo]
of AnsiString = ('
BuildNumber', '
BuildType', '
Manufacturer', '
Name', '
SerialNumber', '
Version');
BiosInfoArr:
array [TBIOSInfo]
of AnsiString = ('
BIOSVersion', '
BuildNumber', '
Description', '
Manufacturer', '
Name', '
SerialNumber', '
Version');
ProcessorInfoArr:
array [TProcessorInfo]
of AnsiString = ('
Description', '
Manufacturer', '
Name', '
ProcessorId', '
UniqueId');
type
THardwareId =
class
private
FOSInfo: TOSInfoSet;
FBIOSInfo: TBIOSInfoSet;
FProcessorInfo: TProcessorInfoSet;
FMotherBoardInfo: TMotherBoardInfoSet;
FBuffer: AnsiString;
function GetHardwareIdHex: AnsiString;
public
// Set the properties to be used in the generation of the hardware id
property MotherBoardInfo: TMotherBoardInfoSet
read FMotherBoardInfo
write FMotherBoardInfo;
property ProcessorInfo: TProcessorInfoSet
read FProcessorInfo
write FProcessorInfo;
property BIOSInfo: TBIOSInfoSet
read FBIOSInfo
write FBIOSInfo;
property OSInfo: TOSInfoSet
read FOSInfo
write FOSInfo;
property Buffer: AnsiString
read FBuffer;
// return the content of the data collected in the system
property HardwareIdHex: AnsiString
read GetHardwareIdHex;
// get a hexadecimal represntation of the data collected
procedure GenerateHardwareId;
// calculate the hardware id
constructor Create(Generate: Boolean = True);
overload;
Destructor Destroy;
override;
end;
implementation
function VarArrayToStr(
const vArray: variant): AnsiString;
function _VarToStr(
const V: variant): AnsiString;
var
Vt: integer;
begin
Vt := VarType(V);
case Vt
of
varSmallint, varInteger:
Result := AnsiString(IntToStr(integer(V)));
varSingle, varDouble, varCurrency:
Result := AnsiString(FloatToStr(Double(V)));
varDate:
Result := AnsiString(VarToStr(V));
varOleStr:
Result := AnsiString(WideString(V));
varBoolean:
Result := AnsiString(VarToStr(V));
varVariant:
Result := AnsiString(VarToStr(variant(V)));
varByte:
Result := AnsiChar(byte(V));
varString:
Result := AnsiString(V);
varArray:
Result := VarArrayToStr(variant(V));
end;
end;
var
i: integer;
begin
Result := '
[';
if (VarType(vArray)
and varArray) = 0
then
Result := _VarToStr(vArray)
else
for i := VarArrayLowBound(vArray, 1)
to VarArrayHighBound(vArray, 1)
do
if i = VarArrayLowBound(vArray, 1)
then
Result := Result + _VarToStr(vArray[i])
else
Result := Result + '
|' + _VarToStr(vArray[i]);
Result := Result + '
]';
end;
function VarStrNull(
const V: OleVariant): AnsiString;
// avoid problems with null strings
begin
Result := '
';
if not VarIsNull(V)
then
begin
if VarIsArray(V)
then
Result := VarArrayToStr(V)
else
Result := AnsiString(VarToStr(V));
end;
end;
{THardwareId}
constructor THardwareId.Create(Generate: Boolean = True);
begin
inherited Create;
CoInitialize(
nil);
FBuffer := '
';
// Set the propeties to be used in the hardware id generation
FMotherBoardInfo := [Mb_SerialNumber, Mb_Manufacturer, Mb_Product, Mb_Model];
FOSInfo := [Os_BuildNumber, Os_BuildType, Os_Manufacturer, Os_Name, Os_SerialNumber, Os_Version];
FBIOSInfo := [Bs_BIOSVersion, Bs_BuildNumber, Bs_Description, Bs_Manufacturer, Bs_Name, Bs_SerialNumber, Bs_Version];
FProcessorInfo := [];
// including the processor info is expensive [Pr_Description,Pr_Manufacturer,Pr_Name,Pr_ProcessorId,Pr_UniqueId];
if Generate
then
GenerateHardwareId;
end;
destructor THardwareId.Destroy;
begin
CoUninitialize;
inherited;
end;
// Main function which collect the system data.
procedure THardwareId.GenerateHardwareId;
var
objSWbemLocator: OleVariant;
objWMIService: OleVariant;
objWbemObjectSet: OleVariant;
oWmiObject: OleVariant;
oEnum: IEnumvariant;
iValue: LongWord;
SDummy: AnsiString;
Mb: TMotherBoardInfo;
Os: TOSInfo;
Bs: TBIOSInfo;
Pr: TProcessorInfo;
begin;
objSWbemLocator := CreateOleObject('
WbemScripting.SWbemLocator');
objWMIService := objSWbemLocator.ConnectServer('
localhost', '
root\cimv2', '
', '
');
if FMotherBoardInfo <> []
then // MotherBoard info
begin
objWbemObjectSet := objWMIService.ExecQuery('
SELECT * FROM Win32_BaseBoard', '
WQL', 0);
oEnum := IUnknown(objWbemObjectSet._NewEnum)
as IEnumvariant;
while oEnum.Next(1, oWmiObject, iValue) = 0
do
begin
for Mb := Low(TMotherBoardInfo)
to High(TMotherBoardInfo)
do
if Mb
in FMotherBoardInfo
then
begin
SDummy := VarStrNull(oWmiObject.Properties_.Item(MotherBoardInfoArr[Mb]).Value);
FBuffer := FBuffer + SDummy;
end;
oWmiObject := Unassigned;
end;
end;
if FOSInfo <> []
then // Windows info
begin
objWbemObjectSet := objWMIService.ExecQuery('
SELECT * FROM Win32_OperatingSystem', '
WQL', 0);
oEnum := IUnknown(objWbemObjectSet._NewEnum)
as IEnumvariant;
while oEnum.Next(1, oWmiObject, iValue) = 0
do
begin
for Os := Low(TOSInfo)
to High(TOSInfo)
do
if Os in FOSInfo
then
begin
SDummy := VarStrNull(oWmiObject.Properties_.Item(OsInfoArr[
Os]).Value);
FBuffer := FBuffer + SDummy;
end;
oWmiObject := Unassigned;
end;
end;
if FBIOSInfo <> []
then // BIOS info
begin
objWbemObjectSet := objWMIService.ExecQuery('
SELECT * FROM Win32_BIOS', '
WQL', 0);
oEnum := IUnknown(objWbemObjectSet._NewEnum)
as IEnumvariant;
while oEnum.Next(1, oWmiObject, iValue) = 0
do
begin
for Bs := Low(TBIOSInfo)
to High(TBIOSInfo)
do
if Bs
in FBIOSInfo
then
begin
SDummy := VarStrNull(oWmiObject.Properties_.Item(BiosInfoArr[Bs]).Value);
FBuffer := FBuffer + SDummy;
end;
oWmiObject := Unassigned;
end;
end;
if FProcessorInfo <> []
then // CPU info
begin
objWbemObjectSet := objWMIService.ExecQuery('
SELECT * FROM Win32_Processor', '
WQL', 0);
oEnum := IUnknown(objWbemObjectSet._NewEnum)
as IEnumvariant;
while oEnum.Next(1, oWmiObject, iValue) = 0
do
begin
for Pr := Low(TProcessorInfo)
to High(TProcessorInfo)
do
if Pr
in FProcessorInfo
then
begin
SDummy := VarStrNull(oWmiObject.Properties_.Item(ProcessorInfoArr[Pr]).Value);
FBuffer := FBuffer + SDummy;
end;
oWmiObject := Unassigned;
end;
end;
end;
function THardwareId.GetHardwareIdHex: AnsiString;
begin
SetLength(Result, Length(FBuffer) * 2);
BinToHex(PAnsiChar(FBuffer), PAnsiChar(Result), Length(FBuffer));
end;
end.