Sys-Info-Driver-Windows
view release on metacpan or search on metacpan
lib/Sys/Info/Driver/Windows/OS.pm view on Meta::CPAN
use Carp qw( croak );
use Sys::Info::Driver::Windows qw( :all );
use Sys::Info::Driver::Windows::OS::Net;
use Sys::Info::Constants qw( :windows_reg :windows_wmi NEW_PERL );
# first row -> All; second row -> NT 4 SP6 and later
my @OSV_NAMES = qw/
STRING MAJOR MINOR BUILD ID
SPMAJOR SPMINOR SUITEMASK PRODUCTTYPE
/;
BEGIN {
*is_win9x = *is_win95 = sub{ Win32::IsWin95() } if ! defined &is_win9x;
*is_winnt = sub{ Win32::IsWinNT() } if ! defined &is_winnt;
}
sub init {
my $self = shift;
$self->{OSVERSION} = undef; # see _populate_osversion
$self->{FILESYSTEM} = undef; # see _populate_fs
return;
}
sub is_root {
# Win32::IsAdminUser(): Perl 5.8.3 Build 809 Monday, Feb 2, 2004
return defined &Win32::IsAdminUser ? Win32::IsAdminUser()
: Win32::IsWin95() ? 1
: 0
;
}
sub node_name { return Win32::NodeName() }
sub edition {
return shift->_populate_osversion->{OSVERSION}{RAW}{EDITION};
}
sub product_type {
my($self, @args) = @_;
$self->_populate_osversion;
my %opt = @args % 2 ? () : @args;
my $raw = $self->{OSVERSION}{RAW}{PRODUCTTYPE};
return $opt{raw} ? $raw : $self->_product_type( $raw );
}
sub name {
my($self, @args) = @_;
$self->_populate_osversion;
my %opt = @args % 2 ? () : @args;
my $id = $opt{long} ? 'LONGNAME' : 'NAME';
return $self->{OSVERSION}{ $opt{edition} ? $id . '_EDITION' : $id };
}
sub version {
my($self, @args) = @_;
my %opt = @args % 2 ? () : @args;
my $version = $self->_populate_osversion->{OSVERSION}{VERSION};
if ( $opt{short} ) {
my @v = split m{[.]}xms, $version;
shift @v;
return join q{.}, @v ;
}
return $version;
}
sub build {
return shift->_populate_osversion->{OSVERSION}{RAW}{BUILD} || 0;
}
sub uptime {
my $self = shift;
return time - $self->tick_count;
}
sub domain_name {
my $self = shift;
return $self->is_win95() ? q{} : Win32::DomainName()
}
sub tick_count {
my $self = shift;
my $tick = Win32::GetTickCount();
return $tick ? $tick / MILISECOND : 0; # in miliseconds
}
sub login_name {
my($self, @args) = @_;
$self->_populate_osversion;
my %opt = @args % 2 ? () : @args;
my $login = Win32::LoginName();
return $opt{real} && $login
? Sys::Info::Driver::Windows::OS::Net->user_fullname( $login )
: $login
;
}
sub logon_server {
my $self = shift;
my $name = $self->login_name || return q{};
return Sys::Info::Driver::Windows::OS::Net->user_logon_server( $name );
}
sub fs {
my $self = shift;
return %{ $self->_populate_fs->{FILESYSTEM} };
}
sub tz {
my $self = shift;
my $tz;
foreach my $object ( in WMI_FOR('Win32_TimeZone') ) {
$tz = $object->Caption;
last;
}
if ( NEW_PERL ) {
require Encode;
my $locale = $self->locale;
my $cp = (split m{[.]}xms, $locale)[LAST_ELEMENT] + 0; # vugly hack
$tz = Encode::decode( "cp$cp", $tz ) if $cp;
}
return $tz;
}
sub meta {
my $self = shift;
my $id = shift;
my $os = ( in WMI_FOR('Win32_OperatingSystem' ) )[0];
my $cs = ( in WMI_FOR('Win32_ComputerSystem' ) )[0];
my $pf = ( in WMI_FOR('Win32_PageFileUsage' ) )[0];
my $idate = $self->_wmidate_to_unix( $os->InstallDate );
my %info;
$info{manufacturer} = $os->Manufacturer;
$info{build_type} = $os->BuildType;
$info{owner} = $os->RegisteredUser;
$info{organization} = $os->Organization;
$info{product_id} = $os->SerialNumber;
$info{install_date} = $idate;
$info{boot_device} = $os->BootDevice;
$info{physical_memory_total} = $os->TotalVisibleMemorySize;
$info{physical_memory_available} = $os->FreePhysicalMemory;
$info{page_file_total} = $os->TotalVirtualMemorySize;
$info{page_file_available} = $os->FreeVirtualMemory;
# windows specific
$info{windows_dir} = $os->WindowsDirectory;
$info{system_dir} = $os->SystemDirectory;
$info{system_manufacturer} = $cs->Manufacturer;
$info{system_model} = $cs->Model;
$info{system_type} = $cs->SystemType;
$info{page_file_path} = $pf ? $pf->Name : undef;
return %info;
}
sub cdkey {
my($self, @args) = @_;
return if Win32::IsWin95(); # not supported
my %opt = @args % 2 ? () : @args;
if ( $opt{office} ) {
my $base = registry()->{ +WIN_REG_OCDKEY };
my @versions;
foreach my $e ( keys %{ $base } ) {
next if $e =~ m{[^0-9\./]}xms; # only get versioned keys
$e =~ s{ / \z }{}xms;
# check all installed office versions
push @versions, $e if $base->{ $e . '/Registration' };
}
my @list;
foreach my $v ( reverse sort { $a <=> $b } @versions ) {
my $key = $base->{ $v . '/Registration' };
my $id = ( keys %{ $key } )[0];
my $val = $key->{ $id . 'DigitalProductId' } || next;
push @list, decode_serial_key( $val );
}
return @list; #return all available keys
}
my $val = registry()->{ +WIN_REG_CDKEY } || return;
return decode_serial_key( $val );
}
sub bitness {
my $self = shift;
my %i = GetSystemInfo();
return $i{wProcessBitness};
}
# ------------------------[ P R I V A T E ]------------------------ #
sub _wmidate_to_unix {
my $self = shift;
my $thing = shift || return;
my($date, $junk) = split m/[.]/xms, $thing;
my($year, $mon, $mday, $hour, $min, $sec) = unpack WIN_WMI_DATE_TMPL, $date;
require Time::Local;
return Time::Local::timelocal( $sec, $min, $hour, $mday, $mon-1, $year );
}
sub _populate_fs {
my $self = shift;
return $self if $self->{FILESYSTEM};
my($FSTYPE, $FLAGS, $MAXCOMPLEN) = Win32::FsType();
if ( !$FSTYPE && Win32::GetLastError() ) {
warn "Can not fetch file system information: $^E\n";
return;
}
my %flag = (
case_sensitive => 0x00000001, #supports case-sensitive filenames
preserve_case => 0x00000002, #preserves the case of filenames
unicode => 0x00000004, #supports Unicode in filenames
acl => 0x00000008, #preserves and enforces ACLs
file_compression => 0x00000010, #supports file-based compression
disk_quotas => 0x00000020, #supports disk quotas
sparse => 0x00000040, #supports sparse files
reparse => 0x00000080, #supports reparse points
remote_storage => 0x00000100, #supports remote storage
compressed_volume => 0x00008000, #is a compressed volume (e.g. DoubleSpace)
object_identifiers => 0x00010000, #supports object identifiers
efs => 0x00020000, #supports the Encrypted File System (EFS)
);
my @fl;
if ( $FLAGS ) {
foreach my $f (keys %flag) {
push @fl, $f => $flag{$f} & $FLAGS ? 1 : 0;
}
}
push @fl, max_file_length => $MAXCOMPLEN if $MAXCOMPLEN;
push @fl, filesystem => $FSTYPE if $FSTYPE; # NTFS/FAT/FAT32
$self->{FILESYSTEM} = { @fl };
return $self;
}
sub _osversion_table {
my $self = shift;
my $OSV = shift;
my $t = sub { $OSV->{MAJOR} == $_[0] && $OSV->{MINOR} == $_[1] };
my $version = join q{.}, $OSV->{ID}, $OSV->{MAJOR}, $OSV->{MINOR};
my $ID = $OSV->{ID};
my($os,$edition);
if ( $ID == 0 ) { $os = 'Win32s' }
elsif ( $ID == 1 ) {
$os = $t->(4,0 ) ? 'Windows 95'
: $t->(4,10) ? 'Windows 98'
: $t->(4,90) ? 'Windows Me'
: "Windows 9x $version"
;
}
elsif ( $ID == 2 ) {
$t->(3,51) ? do { $os = 'Windows NT 3.51' }
( run in 0.801 second using v1.01-cache-2.11-cpan-5511b514fd6 )