diff --git a/Win32.pm b/Win32.pm index 2ad726a..f0be017 100644 --- a/Win32.pm +++ b/Win32.pm @@ -30,6 +30,7 @@ package Win32; ); @EXPORT_OK = qw( GetOSName + GetOSFullVersion SW_HIDE SW_SHOWNORMAL SW_SHOWMINIMIZED @@ -378,6 +379,14 @@ sub GetOSDisplayName { return $name; } +sub GetOSFullVersion { + my(undef, $major, $minor, $build) = Win32::GetOSVersion(); + my @os_full_version = ($major, $minor, $build); + my $rev = Win32::GetOSUpdateBuildRevision(); + push(@os_full_version, $rev) if(defined $rev); + return wantarray ? @os_full_version : join('.',@os_full_version); +} + sub _GetSystemMetrics { my($index,$metrics) = @_; return Win32::GetSystemMetrics($index) unless ref $metrics; @@ -596,6 +605,8 @@ sub _GetOSName { } else { $desc = " Build $build"; + my $ubr = Win32::GetOSUpdateBuildRevision(); + $desc.=".$ubr" if(defined $ubr); } } else { @@ -620,6 +631,8 @@ sub _GetOSName { } else { $desc = "Build $build"; + my $ubr = Win32::GetOSUpdateBuildRevision(); + $desc.=".$ubr" if(defined $ubr); } } } @@ -1092,6 +1105,15 @@ Win32::GetProductInfo() and Win32::GetSystemMetrics() functions provide the base information to check for certain capabilities, or for families of OS releases. +=item Win32::GetOSFullVersion() + +In scalar context returns a string containing the full version of the +Win32 operating system (including revision number if applicable), in +following format: C (example for Windows 10 +version 22H2 build 19045.4170: C<"10.0.19045.4170">). In list context +returns the same numbers in a list instead: +C<($major, $minor, $build, $revision)> (example: C<(10, 0, 19045, 4170)>). + =item Win32::GetOSName() In scalar context returns the name of the Win32 operating system @@ -1144,6 +1166,13 @@ different major/minor version number than Windows XP. Similarly the name "WinWin32s" should have been "Win32s" but has been kept as-is for backwards compatibility reasons too. +=item Win32::GetOSUpdateBuildRevision() + +Returns the current Update Build Revision (UBR) of the Win32 operating +system if applicable, or undef otherwise. The UBR number is the last +part of the build numbers used by Microsoft to identify the exact +Windows revisions. + =item Win32::GetOSVersion() [CORE] Returns the list (STRING, MAJOR, MINOR, BUILD, ID), where the diff --git a/Win32.xs b/Win32.xs index 3166c29..6495681 100644 --- a/Win32.xs +++ b/Win32.xs @@ -1132,6 +1132,40 @@ XS(w32_GetOSVersion) PUTBACK; } +XS(w32_GetOSUpdateBuildRevision) +{ + dXSARGS; + LONG status; + DWORD val, val_size = sizeof(val); + PFNRegGetValueA pfnRegGetValueA; + HMODULE module; + + if (items) + Perl_croak(aTHX_ "usage: Win32::GetOSUpdateBuildRevision()"); + + EXTEND(SP, 1); + + module = GetModuleHandleA("advapi32.dll"); + GETPROC(RegGetValueA); + if (!pfnRegGetValueA) + XSRETURN_UNDEF; + + status = pfnRegGetValueA( + HKEY_LOCAL_MACHINE, + "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", + "UBR", + RRF_RT_REG_DWORD, + NULL, + &val, + &val_size + ); + + if (status == ERROR_SUCCESS) + XSRETURN_IV(val); + + XSRETURN_UNDEF; +} + XS(w32_IsWinNT) { dXSARGS; @@ -2058,6 +2092,7 @@ BOOT: newXS("Win32::DomainName", w32_DomainName, file); newXS("Win32::FsType", w32_FsType, file); newXS("Win32::GetOSVersion", w32_GetOSVersion, file); + newXS("Win32::GetOSUpdateBuildRevision", w32_GetOSUpdateBuildRevision, file); newXS("Win32::IsWinNT", w32_IsWinNT, file); newXS("Win32::IsWin95", w32_IsWin95, file); newXS("Win32::FormatMessage", w32_FormatMessage, file);