Skip to content

Commit ce28b2f

Browse files
authored
Merge pull request #19 from perl-libwin32/pr/15
Improve GetOSDisplaName for Windows 10 and WIndows 2016+ Server releases
2 parents 03d02fc + 57ca47d commit ce28b2f

File tree

2 files changed

+225
-96
lines changed

2 files changed

+225
-96
lines changed

Win32.pm

Lines changed: 179 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ sub VER_SUITE_STORAGE_SERVER () { 0x00002000 } # Windows Storage Serve
174174
sub VER_SUITE_TERMINAL () { 0x00000010 } # Terminal Services is installed. This value is always set.
175175
# If VER_SUITE_TERMINAL is set but VER_SUITE_SINGLEUSERTS is not set, the system is running in application server mode.
176176
sub VER_SUITE_WH_SERVER () { 0x00008000 } # Windows Home Server is installed.
177+
sub VER_SUITE_MULTIUSERTS () { 0x00020000 } # AppServer mode is enabled.
177178

178179

179180
sub SM_TABLETPC () { 86 }
@@ -359,7 +360,8 @@ sub GetOSDisplayName {
359360
$desc =~ s/^\s*//;
360361
s/(200.)/$name Server $1/;
361362
}
362-
s/^Windows (20(03|08|12))/Windows Server $1/;
363+
s/^Windows (20(03|08|12|16|19))/Windows Server $1/;
364+
s/^Windows SAC/Windows Server/;
363365
}
364366
}
365367
$name .= " $desc" if length $desc;
@@ -528,12 +530,12 @@ sub _GetOSName {
528530
}
529531
}
530532
elsif ($minor == 2) {
531-
if ($producttype == VER_NT_WORKSTATION) {
532-
$os = "8";
533-
}
534-
else {
535-
$os = "2012";
536-
}
533+
if ($producttype == VER_NT_WORKSTATION) {
534+
$os = "8";
535+
}
536+
else {
537+
$os = "2012";
538+
}
537539
}
538540
elsif ($minor == 3) {
539541
if ($producttype == VER_NT_WORKSTATION) {
@@ -546,64 +548,130 @@ sub _GetOSName {
546548
}
547549
}
548550
elsif ($major == 10) {
549-
$os = '10';
551+
if ($producttype == VER_NT_WORKSTATION) {
552+
# Build numbers from https://en.wikipedia.org/wiki/Windows_10_version_history
553+
$os = '10';
554+
if (9841 <= $build && $build <= 10240) {
555+
$desc = " Version 1507";
556+
$desc .= " (Preview Build $build)" if $build < 10240;
557+
$desc .= " (RTM)" if $build == 10240;
558+
}
559+
elsif (10525 <= $build && $build <= 10586) {
560+
$desc = " Version 1511 (November Update)";
561+
$desc .= " (Preview Build $build)" if $build < 10586;
562+
}
563+
elsif (11082 <= $build && $build <= 14393) {
564+
$desc = " Version 1607 (Anniversary Update)";
565+
$desc .= " (Preview Build $build)" if $build < 14393;
566+
}
567+
elsif (14901 <= $build && $build <= 15063) {
568+
$desc = " Version 1703 (Creators Update)";
569+
$desc .= " (Preview Build $build)" if $build < 15063;
570+
}
571+
elsif (16170 <= $build && $build <= 16299) {
572+
$desc = " Version 1709 (Fall Creators Update)";
573+
$desc .= " (Preview Build $build)" if $build < 16299;
574+
}
575+
elsif (16353 <= $build && $build <= 17134) {
576+
$desc = " Version 1803 (April 2018 Update)";
577+
$desc .= " (Preview Build $build)" if $build < 17134;
578+
}
579+
elsif (17604 <= $build && $build <= 17763) {
580+
$desc = " Version 1809 (October 2018 Update)";
581+
$desc .= " (Preview Build $build)" if $build < 17763;
582+
}
583+
elsif (18204 <= $build && $build <= 18362) {
584+
$desc = " Version 1903 (May 2019 Update)";
585+
$desc .= " (Preview Build $build)" if $build < 18362;
586+
}
587+
else {
588+
$desc = " Build $build";
589+
}
590+
}
591+
else {
592+
if ($build == 14393) {
593+
$os = "2016";
594+
$desc = "Version 1607";
595+
}
596+
elsif ($build == 17763) {
597+
$os = "2019";
598+
$desc = "Version 1809";
599+
}
600+
else {
601+
$os = "Server";
602+
if ($build == 16299) {
603+
$desc = "Version 1709";
604+
}
605+
elsif ($build == 17134) {
606+
$desc = "Version 1803";
607+
}
608+
elsif ($build == 18362) {
609+
$desc = "Version 1903";
610+
}
611+
else {
612+
$desc = "Build $build";
613+
}
614+
}
615+
}
550616
}
551617

552618
if ($major >= 6) {
553-
if ($productinfo == PRODUCT_ULTIMATE) {
554-
$desc .= " Ultimate";
555-
}
556-
elsif ($productinfo == PRODUCT_HOME_PREMIUM) {
557-
$desc .= " Home Premium";
558-
}
559-
elsif ($productinfo == PRODUCT_HOME_BASIC) {
560-
$desc .= " Home Basic";
561-
}
562-
elsif ($productinfo == PRODUCT_ENTERPRISE) {
563-
$desc .= " Enterprise";
564-
}
565-
elsif ($productinfo == PRODUCT_BUSINESS) {
566-
# "Windows 7 Business" had a name change to "Windows 7 Professional"
567-
$desc .= $minor == 0 ? " Business" : " Professional";
568-
}
569-
elsif ($productinfo == PRODUCT_STARTER) {
570-
$desc .= " Starter";
571-
}
572-
elsif ($productinfo == PRODUCT_CLUSTER_SERVER) {
573-
$desc .= " HPC Server";
574-
}
575-
elsif ($productinfo == PRODUCT_DATACENTER_SERVER) {
576-
$desc .= " Datacenter";
577-
}
578-
elsif ($productinfo == PRODUCT_DATACENTER_SERVER_CORE) {
579-
$desc .= " Datacenter Edition (core installation)";
580-
}
581-
elsif ($productinfo == PRODUCT_ENTERPRISE_SERVER) {
582-
$desc .= " Enterprise";
583-
}
584-
elsif ($productinfo == PRODUCT_ENTERPRISE_SERVER_CORE) {
585-
$desc .= " Enterprise Edition (core installation)";
586-
}
587-
elsif ($productinfo == PRODUCT_ENTERPRISE_SERVER_IA64) {
588-
$desc .= " Enterprise Edition for Itanium-based Systems";
589-
}
590-
elsif ($productinfo == PRODUCT_SMALLBUSINESS_SERVER) {
591-
$desc .= " Small Business Server";
592-
}
593-
elsif ($productinfo == PRODUCT_SMALLBUSINESS_SERVER_PREMIUM) {
594-
$desc .= " Small Business Server Premium Edition";
595-
}
596-
elsif ($productinfo == PRODUCT_STANDARD_SERVER) {
597-
$desc .= " Standard";
598-
}
599-
elsif ($productinfo == PRODUCT_STANDARD_SERVER_CORE) {
600-
$desc .= " Standard Edition (core installation)";
601-
}
602-
elsif ($productinfo == PRODUCT_WEB_SERVER) {
603-
$desc .= " Web Server";
604-
}
605-
elsif ($productinfo == PRODUCT_PROFESSIONAL) {
606-
$desc .= " Professional";
619+
if ($major == 6) {
620+
if ($productinfo == PRODUCT_ULTIMATE) {
621+
$desc .= " Ultimate";
622+
}
623+
elsif ($productinfo == PRODUCT_HOME_PREMIUM) {
624+
$desc .= " Home Premium";
625+
}
626+
elsif ($productinfo == PRODUCT_HOME_BASIC) {
627+
$desc .= " Home Basic";
628+
}
629+
elsif ($productinfo == PRODUCT_ENTERPRISE) {
630+
$desc .= " Enterprise";
631+
}
632+
elsif ($productinfo == PRODUCT_BUSINESS) {
633+
# "Windows 7 Business" had a name change to "Windows 7 Professional"
634+
$desc .= $minor == 0 ? " Business" : " Professional";
635+
}
636+
elsif ($productinfo == PRODUCT_STARTER) {
637+
$desc .= " Starter";
638+
}
639+
elsif ($productinfo == PRODUCT_CLUSTER_SERVER) {
640+
$desc .= " HPC Server";
641+
}
642+
elsif ($productinfo == PRODUCT_DATACENTER_SERVER) {
643+
$desc .= " Datacenter";
644+
}
645+
elsif ($productinfo == PRODUCT_DATACENTER_SERVER_CORE) {
646+
$desc .= " Datacenter Edition (core installation)";
647+
}
648+
elsif ($productinfo == PRODUCT_ENTERPRISE_SERVER) {
649+
$desc .= " Enterprise";
650+
}
651+
elsif ($productinfo == PRODUCT_ENTERPRISE_SERVER_CORE) {
652+
$desc .= " Enterprise Edition (core installation)";
653+
}
654+
elsif ($productinfo == PRODUCT_ENTERPRISE_SERVER_IA64) {
655+
$desc .= " Enterprise Edition for Itanium-based Systems";
656+
}
657+
elsif ($productinfo == PRODUCT_SMALLBUSINESS_SERVER) {
658+
$desc .= " Small Business Server";
659+
}
660+
elsif ($productinfo == PRODUCT_SMALLBUSINESS_SERVER_PREMIUM) {
661+
$desc .= " Small Business Server Premium Edition";
662+
}
663+
elsif ($productinfo == PRODUCT_STANDARD_SERVER) {
664+
$desc .= " Standard";
665+
}
666+
elsif ($productinfo == PRODUCT_STANDARD_SERVER_CORE) {
667+
$desc .= " Standard Edition (core installation)";
668+
}
669+
elsif ($productinfo == PRODUCT_WEB_SERVER) {
670+
$desc .= " Web Server";
671+
}
672+
elsif ($productinfo == PRODUCT_PROFESSIONAL) {
673+
$desc .= " Professional";
674+
}
607675
}
608676

609677
if ($arch == PROCESSOR_ARCHITECTURE_INTEL) {
@@ -612,7 +680,7 @@ sub _GetOSName {
612680
elsif ($arch == PROCESSOR_ARCHITECTURE_AMD64) {
613681
$desc .= " (64-bit)";
614682
}
615-
}
683+
}
616684
}
617685

618686
unless (defined $os) {
@@ -998,6 +1066,10 @@ GetOSVersion() in list context.
9981066
The description will also include tags for other special editions,
9991067
like "R2", "Media Center", "Tablet PC", or "Starter Edition".
10001068
1069+
In the Windows 10 / Server Semi-Annual Channel era, the description may
1070+
contain the relevant ReleaseId value, but this is only inferred from
1071+
the build number, not determined absolutely.
1072+
10011073
Currently the possible values for the OS name are
10021074
10031075
WinWin32s
@@ -1013,6 +1085,12 @@ Currently the possible values for the OS name are
10131085
WinVista
10141086
Win2008
10151087
Win7
1088+
Win8
1089+
Win8.1
1090+
Win10
1091+
Win2016
1092+
Win2019
1093+
WinSAC
10161094
10171095
This routine is just a simple interface into GetOSVersion(). More
10181096
specific or demanding situations should use that instead. Another
@@ -1038,30 +1116,36 @@ For the ID, the values are 0 for Win32s, 1 for Windows 9X/Me and 2 for
10381116
Windows NT/2000/XP/2003/Vista/2008/7. In scalar context it returns just
10391117
the ID.
10401118
1041-
Currently known values for ID MAJOR and MINOR are as follows:
1042-
1043-
OS ID MAJOR MINOR
1044-
Win32s 0 - -
1045-
Windows 95 1 4 0
1046-
Windows 98 1 4 10
1047-
Windows Me 1 4 90
1048-
1049-
Windows NT 3.51 2 3 51
1050-
Windows NT 4 2 4 0
1051-
1052-
Windows 2000 2 5 0
1053-
Windows XP 2 5 1
1054-
Windows Server 2003 2 5 2
1055-
Windows Server 2003 R2 2 5 2
1056-
Windows Home Server 2 5 2
1057-
1058-
Windows Vista 2 6 0
1059-
Windows Server 2008 2 6 0
1060-
Windows 7 2 6 1
1061-
Windows Server 2008 R2 2 6 1
1062-
Windows 8 2 6 2
1063-
Windows Server 2012 2 6 2
1064-
1119+
Currently known values for ID MAJOR MINOR and BUILD are as follows:
1120+
1121+
OS ID MAJOR MINOR BUILD
1122+
Win32s 0 - - -
1123+
Windows 95 1 4 0 -
1124+
Windows 98 1 4 10 -
1125+
Windows Me 1 4 90 -
1126+
1127+
Windows NT 3.51 2 3 51 -
1128+
Windows NT 4 2 4 0 -
1129+
1130+
Windows 2000 2 5 0 -
1131+
Windows XP 2 5 1 -
1132+
Windows Server 2003 2 5 2 -
1133+
Windows Server 2003 R2 2 5 2 -
1134+
Windows Home Server 2 5 2 -
1135+
1136+
Windows Vista 2 6 0 -
1137+
Windows Server 2008 2 6 0 -
1138+
Windows 7 2 6 1 -
1139+
Windows Server 2008 R2 2 6 1 -
1140+
Windows 8 2 6 2 -
1141+
Windows Server 2012 2 6 2 -
1142+
Windows 8.1 2 6 2 -
1143+
Windows Server 2012 R2 2 6 2 -
1144+
1145+
Windows 10 2 10 0 -
1146+
Windows Server 2016 2 10 0 14393
1147+
Windows Server 2019 2 10 0 17677
1148+
10651149
On Windows NT 4 SP6 and later this function returns the following
10661150
additional values: SPMAJOR, SPMINOR, SUITEMASK, PRODUCTTYPE.
10671151
@@ -1081,8 +1165,14 @@ The version numbers for Windows 8 and Windows Server 2012 are
10811165
identical; the PRODUCTTYPE field must be used to differentiate between
10821166
them.
10831167
1168+
For modern Windows releases, the major and minor version numbers are
1169+
identical. The PRODUCTTYPE field must be used to differentiate between
1170+
Windows 10 and Server releases. The BUILD field is used to
1171+
differentiate Windows Server versions: currently 2016, 2019, and
1172+
Semi-Annual Channel releases.
1173+
10841174
SPMAJOR and SPMINOR are the version numbers of the latest
1085-
installed service pack.
1175+
installed service pack. (In the Windows 10 era, these are unused.)
10861176
10871177
SUITEMASK is a bitfield identifying the product suites available on
10881178
the system. Known bits are:
@@ -1103,6 +1193,7 @@ the system. Known bits are:
11031193
VER_SUITE_STORAGE_SERVER 0x00002000
11041194
VER_SUITE_COMPUTE_SERVER 0x00004000
11051195
VER_SUITE_WH_SERVER 0x00008000
1196+
VER_SUITE_MULTIUSERTS 0x00020000
11061197
11071198
The VER_SUITE_xxx names are listed here to cross reference the Microsoft
11081199
documentation. The Win32 module does not provide symbolic names for these

0 commit comments

Comments
 (0)