package Sys::Info::Driver::Windows::OS::Editions; use strict; use warnings; use Sys::Info::Driver::Windows qw( :metrics :WMI ); use constant RE_X86 => qr{ X86}xmsi; use constant RE_AMD64 => qr{AMD64}xmsi; use constant RE_IA64 => qr{ IA64}xmsi; ## no critic ( ValuesAndExpressions::ProhibitMagicNumbers ) ## no critic ( ValuesAndExpressions::RequireNumberSeparators ) our $VERSION = '0.78'; my %VISTA_EDITION = ( 0x00000006 => q{Business Edition}, 0x00000010 => q{Business N Edition}, 0x00000004 => q{Enterprise Edition}, 0x00000002 => q{Home Basic Edition}, 0x00000005 => q{Home Basic N Edition}, 0x00000003 => q{Home Premium Edition}, 0x0000000B => q{Starter Edition}, 0x00000001 => q{Ultimate Edition}, ); my %SERVER08_EDITION = ( 0x00000012 => q{Cluster Server Edition}, 0x00000008 => q{Datacenter Edition Full Installation}, # Windows Server ... 0x0000000C => q{Datacenter Edition Core Installation}, # Windows Server ... 0x0000000A => q{Enterprise Edition Full Installation}, # Windows Server ... 0x0000000E => q{Enterprise Edition Core Installation}, # Windows Server ... 0x0000000F => q{Enterprise Edition For Itanium Based Systems}, # Windows Server ... 0x00000013 => q{Home Server Edition}, 0x00000018 => q{Server For Small Business Edition}, 0x00000009 => q{Small Business Server}, 0x00000019 => q{Small Business Server Premium Edition}, 0x00000007 => q{Server Standard Edition Full Installation}, 0x0000000D => q{Server Standard Edition Core Installation}, 0x00000017 => q{Storage Server Enterprise Edition}, 0x00000014 => q{Storage Server Express Edition}, 0x00000015 => q{Storage Server Standard Edition}, 0x00000016 => q{Storage Server Workgroup Edition}, 0x00000011 => q{Web Server Edition}, ); sub _cpu_arch { my $self = shift; require Sys::Info::Device; my $cpu = Sys::Info::Device->new( 'CPU' ); foreach my $cpu ( $cpu->identify ) { # get the first available one return $cpu->{architecture} if $cpu->{architecture}; } return; } sub _xp_or_03 { my $self = shift; my $edition_ref = shift; my $osname_ref = shift; my $OSV = shift; my $mask = $OSV->{RAW}{SUITEMASK}; my $pt = $OSV->{RAW}{PRODUCTTYPE}; my $arch = $self->_cpu_arch || q{}; my $metric = GetSystemMetrics( SM_SERVERR2 ); ${$osname_ref} = 'Windows Server 2003'; my $id = $mask & 0x00000080 ? 1 : $mask & 0x00000002 ? 2 : 3 ; my $dispatch = '_xp_or_03_case' . $id; return $self->$dispatch( $metric, $arch, $edition_ref, $osname_ref, $pt ); } sub _xp_or_03_case1 { my($self, $metric, $arch, $edition_ref) = @_; if ( $metric ) { ${$edition_ref} = $arch =~ RE_X86 ? 'R2 Datacenter Edition' : $arch =~ RE_AMD64 ? 'R2 x64 Datacenter Edition' : 'unknown'; } else { ${$edition_ref} = $arch =~ RE_X86 ? 'Datacenter Edition' : $arch =~ RE_AMD64 ? 'Datacenter x64 Edition' : $arch =~ RE_IA64 ? 'Datacenter Edition Itanium' : 'unknown'; } return; } sub _xp_or_03_case2 { my($self, $metric, $arch, $edition_ref) = @_; if ( $metric ) { ${$edition_ref} = $arch =~ RE_X86 ? 'R2 Enterprise Edition' : $arch =~ RE_AMD64 ? 'R2 x64 Enterprise Edition' : 'unknown'; } else { ${$edition_ref} = $arch =~ RE_X86 ? 'Enterprise Edition' : $arch =~ RE_AMD64 ? 'Enterprise x64 Edition' : $arch =~ RE_IA64 ? 'Enterprise Edition Itanium' : 'unknown'; } return; } sub _xp_or_03_case3 { my($self, $metric, $arch, $edition_ref, $osname_ref, $pt) = @_; if ( $metric ) { ${$edition_ref} = $arch =~ RE_X86 ? 'R2 Standard Edition' : $arch =~ RE_AMD64 ? 'R2 x64 Standard Edition' : 'unknown'; } elsif ( $pt > 1 ) { ${$edition_ref} = $arch =~ RE_X86 ? 'Standard Edition' : $arch =~ RE_AMD64 ? 'Standard x64 Edition' : 'unknown'; } elsif ( $pt == 1 ) { ${$osname_ref} = 'Windows XP'; ${$edition_ref} = $arch =~ RE_IA64 ? '64 bit Edition Version 2003' : $arch =~ RE_AMD64 ? 'Professional x64 Edition' : 'unknown'; } else { ${$edition_ref} = 'unknown'; } return; } sub _xp_editions { my $self = shift; my $edition_ref = shift; my $osname_ref = shift; my $OSV = shift; my $arch = $self->_cpu_arch; ${$osname_ref} = 'Windows XP'; ${$edition_ref} = GetSystemMetrics(SM_TABLETPC) ? 'Tablet PC Edition' : GetSystemMetrics(SM_MEDIACENTER) ? 'Media Center Edition' : GetSystemMetrics(SM_STARTER) ? 'Starter Edition' : $arch =~ RE_X86 ? 'Professional' : $arch =~ RE_IA64 ? '64-bit Edition for Itanium systems' : q{}; return; } sub _2k_03_xp { my $self = shift; my $edition_ref = shift; my $osname_ref = shift; my $OSV = shift; my $mask = $OSV->{RAW}{SUITEMASK}; my $pt = $OSV->{RAW}{PRODUCTTYPE}; ${$osname_ref} = 'Windows 2000'; if ( $mask & 0x00000080 ) { ## no critic (ControlStructures::ProhibitCascadingIfElse) ${$edition_ref} = 'Datacenter Server'; } elsif ( $mask & 0x00000002) { ${$edition_ref} = 'Advanced Server'; } elsif (! $mask && $pt == 1 ) { ${$edition_ref} = 'Professional'; } elsif (! $mask && $pt > 1 ) { ${$edition_ref} = 'Server'; } elsif ( $mask & 0x00000400 ) { ${$osname_ref} = 'Windows Server 2003'; ${$edition_ref} = GetSystemMetrics(SM_SERVERR2) ? 'R2 Web Edition' : 'Web Edition'; } elsif ( $mask & 0x00004000) { ${$osname_ref} = 'Windows Server 2003'; ${$edition_ref} = GetSystemMetrics(SM_SERVERR2) ? 'R2 Compute Cluster Edition' : 'Compute Cluster Edition'; } elsif ( $mask & 0x00002000) { ${$osname_ref} = 'Windows Server 2003'; ${$edition_ref} = GetSystemMetrics(SM_SERVERR2) ? 'R2 Storage' : 'Storage'; } elsif ($mask & 0x00000040 ) { ${$osname_ref} = 'Windows XP'; ${$edition_ref} = 'Embedded'; } elsif ($mask & 0x00000200) { ${$osname_ref} = 'Windows XP'; ${$edition_ref} = 'Home Edition'; } else { warn "Unable to identify this Windows version\n"; } return; } sub _vista_or_08 { my $self = shift; my $edition_ref = shift; my $osname_ref = shift; my $WMI_OS = WMI_FOR('Win32_OperatingSystem'); return if ! $WMI_OS; # fall-back my $item = ( in $WMI_OS )[0]; my $SKU = $item->OperatingSystemSKU; my $caption = $item->Caption; if ( my $vista = $VISTA_EDITION{ $SKU } ) { ${$edition_ref} = $vista; ${$osname_ref} = 'Windows Vista'; } elsif ( my $ws08 = $SERVER08_EDITION{ $SKU } ) { ${$edition_ref} = $ws08; ${$osname_ref} = 'Windows Server 2008'; # oh yeah! } else { warn "Unable to identify this Windows version 6. Marking as Vista\n"; ${$osname_ref} = 'Windows Vista'; } return; } sub _win7 { my $self = shift; my $edition_ref = shift; my $osname_ref = shift; my $WMI_OS = WMI_FOR('Win32_OperatingSystem'); return if ! $WMI_OS; # fall-back my $item = ( in $WMI_OS )[0]; my $SKU = $item->OperatingSystemSKU; ${$osname_ref} = 'Windows 7'; if ( my $win7 = $VISTA_EDITION{ $SKU } ) { ${$edition_ref} = $win7; } else { (my $caption = $item->Caption) =~ s{ .+? Windows \s 7 \s? }{}xms; ${$edition_ref} = $self->trim($caption) if $caption; } return; } 1; __END__ =pod =head1 NAME Sys::Info::Driver::Windows::OS::Editions - Interface to identify Windows editions =head1 SYNOPSIS None. Used internally. =head1 DESCRIPTION This document describes version C<0.78> of C released on C<17 April 2011>. Although there are not much Windows versions, there are ridiculously lots of editions of Windows versions after Windows 2000. This module uses C, C and CPU architecture to define the correct operating system name and edition. =head1 SEE ALSO L, L, L. =head1 AUTHOR Burak Gursoy . =head1 COPYRIGHT Copyright 2006 - 2011 Burak Gursoy. All rights reserved. =head1 LICENSE This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.12.2 or, at your option, any later version of Perl 5 you may have available. =cut