322 lines
9.2 KiB
Perl
322 lines
9.2 KiB
Perl
package sysinfo;
|
|
|
|
use strict;
|
|
|
|
require Exporter;
|
|
@sysinfo::ISA = qw(Exporter);
|
|
@sysinfo::EXPORT = qw(
|
|
read_cpus
|
|
get_os_data
|
|
get_system_info
|
|
get_memory_status
|
|
get_wbem_info
|
|
get_install_info
|
|
get_sysinfo
|
|
print_sysinfo
|
|
);
|
|
|
|
use POSIX qw(strftime);
|
|
use Win32;
|
|
use Win32::OLE qw(in);
|
|
use Win32::API;
|
|
use Win32::TieRegistry;
|
|
|
|
$Registry->Delimiter('/');
|
|
$Registry->ArrayValues(1);
|
|
|
|
use constant wbemFlagReturnImmediately => 0x10;
|
|
use constant wbemFlagForwardOnly => 0x20;
|
|
|
|
my $PROCESSOR_ARCHITECTURE = {
|
|
0 => 'x86',
|
|
1 => 'MIPS',
|
|
2 => 'Alpha',
|
|
3 => 'PPC',
|
|
5 => 'ARM',
|
|
6 => 'IA64',
|
|
9 => 'x64'
|
|
};
|
|
|
|
sub get_value ($)
|
|
{
|
|
my ($node) = @_;
|
|
|
|
my $value = $$node[0];
|
|
return undef unless defined $value;
|
|
my $type = $$node[1];
|
|
if ($type == 4 && $value =~ /^0x[0-9a-f]+$/oi) {
|
|
# REG_DWORD
|
|
return hex($value);
|
|
}
|
|
return $value;
|
|
}
|
|
|
|
sub defines ()
|
|
{
|
|
Win32::API::Struct->typedef(
|
|
SYSTEM_INFO => qw {
|
|
WORD wProcessorArchitecture;
|
|
WORD wReserved;
|
|
DWORD dwPageSize;
|
|
UINT_PTR lpMinimumApplicationAddress;
|
|
UINT_PTR lpMaximumApplicationAddress;
|
|
LPDWORD dwActiveProcessorMask;
|
|
DWORD dwNumberOfProcessors;
|
|
DWORD dwProcessorType;
|
|
DWORD dwAllocationGranularity;
|
|
WORD wProcessorLevel;
|
|
WORD wProcessorRevision;
|
|
}
|
|
);
|
|
Win32::API::Struct->typedef(
|
|
MEMORYSTATUSEX => qw {
|
|
DWORD dwLength;
|
|
DWORD MemLoad;
|
|
DWORD TotalPhysLo;
|
|
DWORD TotalPhysHi;
|
|
DWORD AvailPhysLo;
|
|
DWORD AvailPhysHi;
|
|
DWORD TotalPageFileLo;
|
|
DWORD TotalPageFileHi;
|
|
DWORD AvailPageFileLo;
|
|
DWORD AvailPageFileHi;
|
|
DWORD TotalVirtualLo;
|
|
DWORD TotalVirtualHi;
|
|
DWORD AvailVirtualLo;
|
|
DWORD AvailVirtualHi;
|
|
DWORD AvailExtendedVirtualLo;
|
|
DWORD AvailExtendedVirtualHi;
|
|
}
|
|
);
|
|
Win32::API->Import('kernel32', 'VOID GetSystemInfo(LPSYSTEM_INFO lpSystemInfo)') ||
|
|
die "Could not locate kernel32.dll - cannot call GetSystemInfo()\n";
|
|
Win32::API->Import('kernel32', 'BOOL GlobalMemoryStatusEx(LPMEMORYSTATUSEX lpMemoryStatus)') ||
|
|
die "Could not locate kernel32.dll - cannot call GlobalMemoryStatusEx()\n";
|
|
}
|
|
|
|
sub get_system_info ()
|
|
{
|
|
my $si = Win32::API::Struct->new('SYSTEM_INFO');
|
|
$si->align('0');
|
|
$si->{'wProcessorArchitecture'} = 0;
|
|
$si->{'wReserved'} = 0;
|
|
$si->{'dwPageSize'} = 0;
|
|
$si->{'lpMinimumApplicationAddress'} = 0;
|
|
$si->{'lpMaximumApplicationAddress'} = 0;
|
|
$si->{'dwActiveProcessorMask'} = 0;
|
|
$si->{'dwNumberOfProcessors'} = 0;
|
|
$si->{'dwProcessorType'} = 0;
|
|
$si->{'dwAllocationGranularity'} = 0;
|
|
$si->{'wProcessorLevel'} = 0;
|
|
$si->{'wProcessorRevision'} = 0;
|
|
GetSystemInfo($si);
|
|
my $arch = $si->{'wProcessorArchitecture'};
|
|
if (! defined $arch) {
|
|
$arch = 'Unknown';
|
|
}
|
|
elsif (! defined $$PROCESSOR_ARCHITECTURE{$arch}) {
|
|
$arch = 'Unknown';
|
|
}
|
|
else {
|
|
$arch = $$PROCESSOR_ARCHITECTURE{$arch};
|
|
}
|
|
return {
|
|
ProcArch => $arch
|
|
};
|
|
}
|
|
|
|
sub get_memory_status ()
|
|
{
|
|
my $ms = Win32::API::Struct->new('MEMORYSTATUSEX');
|
|
$ms->align('auto');
|
|
$ms->{'dwLength'} = $ms->sizeof();
|
|
$ms->{'MemLoad'} = 0;
|
|
$ms->{'TotalPhysLo'} = 0;
|
|
$ms->{'TotalPhysHi'} = 0;
|
|
$ms->{'AvailPhysLo'} = 0;
|
|
$ms->{'AvailPhysHi'} = 0;
|
|
$ms->{'TotalPageFileLo'} = 0;
|
|
$ms->{'TotalPageFileHi'} = 0;
|
|
$ms->{'AvailPageFileLo'} = 0;
|
|
$ms->{'AvailPageFileHi'} = 0;
|
|
$ms->{'TotalVirtualLo'} = 0;
|
|
$ms->{'TotalVirtualHi'} = 0;
|
|
$ms->{'AvailVirtualLo'} = 0;
|
|
$ms->{'AvailVirtualHi'} = 0;
|
|
$ms->{'AvailExtendedVirtualLo'} = 0;
|
|
$ms->{'AvailExtendedVirtualHi'} = 0;
|
|
GlobalMemoryStatusEx($ms);
|
|
return undef if $ms->{dwLength} == 0;
|
|
my $memory = {};
|
|
if (defined $ms->{'TotalPhysLo'} && defined $ms->{'TotalPhysHi'}) {
|
|
$$memory{TotalPhysMB} = $ms->{'TotalPhysHi'} * 4096 +
|
|
int(($ms->{'TotalPhysLo'} + 1048575) / 1048576);
|
|
}
|
|
if (defined $ms->{'TotalPageFileLo'} && defined $ms->{'TotalPageFileHi'}) {
|
|
$$memory{TotalPageFileMB} = $ms->{'TotalPageFileHi'} * 4096 +
|
|
int(($ms->{'TotalPageFileLo'} + 1048575) / 1048576);
|
|
}
|
|
return $memory;
|
|
}
|
|
|
|
sub get_nodename ()
|
|
{
|
|
return Win32::NodeName();
|
|
}
|
|
|
|
sub get_os_data ()
|
|
{
|
|
my $guid = $Registry->{'HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Cryptography/MachineGuid'};
|
|
die 'Cannot find HKLM\\SOFTWARE\\Microsoft\\Cryptography\\MachineGuid' unless defined $guid;
|
|
my $nodename = get_nodename();
|
|
my $domainname = Win32::DomainName();
|
|
my $osdispname = Win32::GetOSDisplayName();
|
|
my $osname = Win32::GetOSName();
|
|
my ($osver, $osmajor, $osminor, $osbuild) = Win32::GetOSVersion();
|
|
my $loginname = Win32::LoginName();
|
|
return {
|
|
MachineGuid => get_value($guid),
|
|
NodeName => $nodename,
|
|
DomainName => $domainname,
|
|
LoginName => $loginname,
|
|
OSDisplayName => $osdispname,
|
|
OSName => $osname,
|
|
OSVersion => $osver,
|
|
OSMajor => $osmajor,
|
|
OSMinor => $osminor,
|
|
OSBuild => $osbuild
|
|
};
|
|
}
|
|
|
|
sub read_cpus ()
|
|
{
|
|
my $cpus = [];
|
|
my $cpu = $Registry->{'HKEY_LOCAL_MACHINE/HARDWARE/Description/System/CentralProcessor'};
|
|
die 'Cannot find HKLM\\HARDWARE\\Description\\System\\CentralProcessor' unless defined $cpu;
|
|
foreach my $name ($cpu->SubKeyNames) {
|
|
my $sub = $cpu->{$name};
|
|
next unless defined $sub;
|
|
my $mhz = get_value($sub->{'~MHz'});
|
|
my $vendor = get_value($sub->{'VendorIdentifier'});
|
|
my $ident = get_value($sub->{'Identifier'});
|
|
my $procname = get_value($sub->{'ProcessorNameString'});
|
|
$procname =~ s/^ +//o;
|
|
$procname =~ s/ +$//o;
|
|
my $code;
|
|
if ($ident =~ /Family (\d+) Model (\d+) Stepping (\d+)/o) {
|
|
$code = $1.'.'.$2.'.'.$3;
|
|
}
|
|
push @$cpus, {
|
|
Id => $name,
|
|
MHz => $mhz,
|
|
Vendor => $vendor,
|
|
Identifier => $ident,
|
|
Code => $code,
|
|
Name => $procname
|
|
};
|
|
}
|
|
return $cpus;
|
|
}
|
|
|
|
sub get_wbem_info ()
|
|
{
|
|
my $nodename = get_nodename();
|
|
my $wmiservice = Win32::OLE->GetObject('winmgmts:\\\\'.$nodename.'\\root\\CIMV2');
|
|
die 'Cannot open WBEM interface' unless defined $wmiservice;
|
|
my $list = $wmiservice->ExecQuery('SELECT * FROM Win32_ComputerSystem', 'WQL', wbemFlagReturnImmediately | wbemFlagForwardOnly);
|
|
|
|
my $wbem = {};
|
|
foreach my $objitem (in $list) {
|
|
$$wbem{PartOfDomain} = $objitem->{'PartOfDomain'};
|
|
$$wbem{Domain} = $objitem->{'Domain'};
|
|
$$wbem{Workgroup} = $objitem->{'Workgroup'};
|
|
$$wbem{Manufacturer} = $objitem->{'Manufacturer'};
|
|
$$wbem{Model} = $objitem->{'Model'};
|
|
}
|
|
return $wbem;
|
|
}
|
|
|
|
sub get_install_info ()
|
|
{
|
|
my $sw = $Registry->{'HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion'};
|
|
die 'Cannot find HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion' unless defined $sw;
|
|
|
|
my $info = {};
|
|
my $installdate = get_value($sw->{'InstallDate'});
|
|
$$info{InstallDateNum} = $installdate;
|
|
$$info{InstallTime} = strftime('%Y-%m-%d %H:%M:%S', localtime($installdate)) if defined $installdate;
|
|
$$info{ProductId} = get_value($sw->{'ProductId'});
|
|
$$info{ProductName} = get_value($sw->{'ProductName'});
|
|
$$info{InstallationType} = get_value($sw->{'InstallationType'});
|
|
$$info{EditionID} = get_value($sw->{'EditionID'});
|
|
$$info{ReleaseId} = get_value($sw->{'ReleaseId'});
|
|
$$info{CSDVersion} = get_value($sw->{'CSDVersion'});
|
|
$$info{CurrentVersion} = get_value($sw->{'CurrentVersion'});
|
|
return $info;
|
|
}
|
|
|
|
sub get_sysinfo ()
|
|
{
|
|
return {
|
|
CPU => read_cpus(),
|
|
OS => get_os_data(),
|
|
System => get_system_info(),
|
|
Memory => get_memory_status(),
|
|
Install => get_install_info(),
|
|
WBEM => get_wbem_info()
|
|
};
|
|
}
|
|
|
|
sub print_sysinfo ()
|
|
{
|
|
my $sysinfo = get_sysinfo();
|
|
|
|
my $cpus = $$sysinfo{CPU};
|
|
my $osdata = $$sysinfo{OS};
|
|
my $systeminfo = $$sysinfo{System};
|
|
my $memorystatus = $$sysinfo{Memory};
|
|
my $install = $$sysinfo{Install};
|
|
my $wbem = $$sysinfo{WBEM};
|
|
|
|
print 'NodeName='.$$osdata{NodeName}.', DomainName='.$$osdata{DomainName}.', LoginName='.$$osdata{LoginName}."\n";
|
|
if (defined $$wbem{PartOfDomain}) {
|
|
print 'NodeStatus='.($$wbem{PartOfDomain} ? 'Domain' : 'Workgroup').
|
|
($$wbem{PartOfDomain} ?
|
|
(defined $$wbem{Domain} ? ', Domain='.$$wbem{Domain} : '') :
|
|
(defined $$wbem{Workgroup} ? ', Workgroup='.$$wbem{Workgroup} : '')).
|
|
"\n";
|
|
}
|
|
print 'MachineGuid='.$$osdata{MachineGuid}."\n";
|
|
if (defined $$wbem{Manufacturer}) {
|
|
print 'Manufacturer='.$$wbem{Manufacturer};
|
|
print ', Model='.$$wbem{Model} if defined $$wbem{Model};
|
|
print "\n";
|
|
}
|
|
print 'NumProc='.scalar(@$cpus);
|
|
print ' TotalPhys='.$$memorystatus{TotalPhysMB}.' MB' if defined $$memorystatus{TotalPhysMB};
|
|
print ' TotalPageFile='.$$memorystatus{TotalPageFileMB}.' MB' if defined $$memorystatus{TotalPageFileMB};
|
|
print ' CPUArch='.$$systeminfo{ProcArch}."\n";
|
|
print 'OSDisplayName='.$$osdata{OSDisplayName}.', OSName='.$$osdata{OSName}."\n";
|
|
if (defined $$install{ProductName}) {
|
|
print 'OSProduct='.$$install{ProductName};
|
|
print ' OSType='.$$install{InstallationType} if defined $$install{InstallationType};
|
|
print ' OSEdition='.$$install{EditionID} if defined $$install{EditionID};
|
|
print ' OSRelease='.$$install{ReleaseId} if defined $$install{ReleaseId};
|
|
print "\n";
|
|
}
|
|
print 'OSVersion='.$$install{CurrentVersion}.' ' if defined $$install{CurrentVersion};
|
|
print 'OSMajor='.$$osdata{OSMajor}.' OSMinor='.$$osdata{OSMinor}.' OSBuild='.$$osdata{OSBuild};
|
|
print ' SPVersion='.$$install{CSDVersion} if defined $$install{CSDVersion};
|
|
print "\n";
|
|
print 'ProductId='.$$install{ProductId};
|
|
print ' Installed='.$$install{InstallTime} if defined $$install{InstallTime};
|
|
print "\n";
|
|
foreach my $cpu (@$cpus) {
|
|
print $$cpu{Id}.': '.$$cpu{MHz}.' MHz '.$$cpu{Name}.' CPUCode='.$$cpu{Code}."\n";
|
|
}
|
|
}
|
|
|
|
defines();
|
|
|
|
1;
|