184 lines
5.2 KiB
ObjectPascal
184 lines
5.2 KiB
ObjectPascal
// **************************************************************************************************
|
|
//
|
|
// CPU, HDD, MB 시리얼 넘버를 얻는 많은 방법중
|
|
// WMI 서비스를 이용하여 심플하게 받아오는 쉬운방법도 있지만
|
|
// 해당 서비스가 실행되고 있어야 하며 관리자권한 및 느리다는 단점이 있다.
|
|
//
|
|
// 아래 소스는 RRUZ.SMBIOS 라이브러리를 바탕으로
|
|
// System Management BIOS 통해 시스템 정보를 읽어 오는 방법이다.
|
|
//
|
|
// 혹자가 테스트 해 봤을때 불법 KMS로 인증받은 OS는 똑 같은 시리얼이 나온다.
|
|
//
|
|
// 2024.12.19 by 0GO2
|
|
//
|
|
// **************************************************************************************************
|
|
unit GO2.SMBios;
|
|
|
|
interface
|
|
|
|
uses
|
|
Winapi.Windows,
|
|
Winapi.IpHlpApi,
|
|
Winapi.IpTypes,
|
|
System.SysUtils;
|
|
|
|
function GetCPUSerialNumber: string;
|
|
function GetMainboardSerialNumber: string;
|
|
function GetHDDSerialNumber: string;
|
|
function GetNetworkAdapterSerialNumber(IncludeWireless: Boolean = False): string;
|
|
function GetHardwareInformation: string;
|
|
|
|
implementation
|
|
|
|
uses
|
|
RRUZ.SMBIOS;
|
|
|
|
function GetCPUSerialNumber: string;
|
|
var
|
|
SMBios: TSMBios;
|
|
ProcessorInfo: TProcessorInformation;
|
|
begin
|
|
Result := '';
|
|
SMBios := TSMBios.Create;
|
|
try
|
|
// ProcessorInfo 정보 가져오기
|
|
for ProcessorInfo in SMBios.ProcessorInfo do
|
|
begin
|
|
// ProcessorID를 16진수 문자열로 변환
|
|
Result := IntToHex(ProcessorInfo.RAWProcessorInformation^.ProcessorID, 16);
|
|
// 첫 번째 프로세서 정보만 가져오고 종료
|
|
Break;
|
|
end;
|
|
finally
|
|
SMBios.Free;
|
|
end;
|
|
end;
|
|
|
|
function GetMainboardSerialNumber: string;
|
|
var
|
|
SMBios: TSMBios;
|
|
BaseBoardInfo: TBaseBoardInformation;
|
|
begin
|
|
Result := '';
|
|
SMBios := TSMBios.Create;
|
|
try
|
|
for BaseBoardInfo in SMBios.BaseBoardInfo do
|
|
begin
|
|
Result := BaseBoardInfo.SerialNumberStr;
|
|
Break;
|
|
end;
|
|
finally
|
|
SMBios.Free;
|
|
end;
|
|
end;
|
|
|
|
function GetHDDSerialNumber: string;
|
|
var
|
|
Drive: string;
|
|
SerialNumber: array[0..255] of Char;
|
|
VolumeSerialNumber: DWORD;
|
|
MaxComponentLength: DWORD;
|
|
FileSystemFlags: DWORD;
|
|
begin
|
|
Drive := 'C:\';
|
|
if GetVolumeInformation(PChar(Drive), nil, 0, @VolumeSerialNumber,
|
|
MaxComponentLength, FileSystemFlags, nil, 0) then
|
|
begin
|
|
Result := IntToHex(VolumeSerialNumber, 8);
|
|
end
|
|
else
|
|
Result := '';
|
|
end;
|
|
|
|
function GetNetworkAdapterSerialNumber(IncludeWireless: Boolean = False): string;
|
|
const
|
|
MIB_IF_TYPE_ETHERNET = 6; // 유선 이더넷
|
|
IF_TYPE_IEEE80211 = 71; // 무선 네트워크
|
|
|
|
var
|
|
AdapterInfo: PIP_ADAPTER_INFO;
|
|
LongSize: ULONG;
|
|
Status: DWORD;
|
|
Adapter: PIP_ADAPTER_INFO;
|
|
begin
|
|
Result := '';
|
|
LongSize := 0;
|
|
|
|
GetAdaptersInfo(nil, LongSize);
|
|
if LongSize = 0 then
|
|
Exit;
|
|
|
|
GetMem(AdapterInfo, LongSize);
|
|
try
|
|
Status := GetAdaptersInfo(AdapterInfo, LongSize);
|
|
if Status = ERROR_SUCCESS then
|
|
begin
|
|
Adapter := AdapterInfo;
|
|
while Adapter <> nil do
|
|
begin
|
|
// 이더넷 또는 무선 어댑터 확인
|
|
if (Adapter^.Type_ = MIB_IF_TYPE_ETHERNET) or
|
|
(IncludeWireless and (Adapter^.Type_ = IF_TYPE_IEEE80211)) then
|
|
begin
|
|
Result := Format('%.2x%.2x%.2x%.2x%.2x%.2x',
|
|
[Adapter^.Address[0],
|
|
Adapter^.Address[1],
|
|
Adapter^.Address[2],
|
|
Adapter^.Address[3],
|
|
Adapter^.Address[4],
|
|
Adapter^.Address[5]]);
|
|
Break;
|
|
end;
|
|
Adapter := Adapter^.Next;
|
|
end;
|
|
end;
|
|
finally
|
|
FreeMem(AdapterInfo);
|
|
end;
|
|
end;
|
|
|
|
function GetHardwareInformation: string;
|
|
var
|
|
SMBios: TSMBios;
|
|
BaseBoardInfo: TBaseBoardInformation;
|
|
ProcessorInfo: TProcessorInformation;
|
|
begin
|
|
Result := '';
|
|
SMBios := TSMBios.Create;
|
|
try
|
|
// CPU 정보
|
|
for ProcessorInfo in SMBios.ProcessorInfo do
|
|
begin
|
|
Result := Result + 'CPU Information:' + #13#10;
|
|
// SerialNumberStr는 SMBIOS Type 4의 Serial Number 필드를 읽어오는데,
|
|
// 대부분의 CPU는 이 필드를 지원하지 않아 'Unknown'으로 표시된다.
|
|
Result := Result + ' Serial Number: ' + IntToHex(ProcessorInfo.RAWProcessorInformation^.ProcessorID, 16) + #13#10;
|
|
Result := Result + ' Manufacturer: ' + ProcessorInfo.ProcessorManufacturerStr + #13#10;
|
|
Result := Result + ' Version: ' + ProcessorInfo.ProcessorVersionStr + #13#10;
|
|
Break;
|
|
end;
|
|
|
|
// 메인보드 정보
|
|
for BaseBoardInfo in SMBios.BaseBoardInfo do
|
|
begin
|
|
Result := Result + #13#10 + 'Mainboard Information:' + #13#10;
|
|
Result := Result + ' Serial Number: ' + BaseBoardInfo.SerialNumberStr + #13#10;
|
|
Result := Result + ' Manufacturer: ' + BaseBoardInfo.ManufacturerStr + #13#10;
|
|
Result := Result + ' Product: ' + BaseBoardInfo.ProductStr + #13#10;
|
|
Break;
|
|
end;
|
|
|
|
// HDD 정보
|
|
Result := Result + #13#10 + 'HDD Information:' + #13#10;
|
|
Result := Result + ' Serial Number: ' + GetHDDSerialNumber + #13#10;
|
|
|
|
// 네트워크 어댑터 정보
|
|
Result := Result + #13#10 + 'Network Adapter Information:' + #13#10;
|
|
Result := Result + ' MAC Address (Wired): ' + GetNetworkAdapterSerialNumber + #13#10;
|
|
Result := Result + ' MAC Address (All): ' + GetNetworkAdapterSerialNumber(True);
|
|
finally
|
|
SMBios.Free;
|
|
end;
|
|
end;
|
|
end.
|