summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Dubois <jand@activestate.com>2003-07-29 12:14:10 -0700
committerJarkko Hietaniemi <jhi@iki.fi>2003-07-30 06:13:55 +0000
commit3e5269857e8d8838cbf4c53cbb042865abeedd0e (patch)
tree5410a90bd2c1b9aa1577c76a8a11f1c39ec68d3b
parent369b44b45b100ebccc1e9e9ec79851683e716faa (diff)
downloadperl-3e5269857e8d8838cbf4c53cbb042865abeedd0e.tar.gz
Extend Win32::GetOSVersion() to return additional information
Message-ID: <i06eivs0h9khken8rloevj68iqu6n45hnq@4ax.com> p4raw-id: //depot/perl@20331
-rw-r--r--lib/Win32.pod52
-rw-r--r--win32/win32.c72
2 files changed, 104 insertions, 20 deletions
diff --git a/lib/Win32.pod b/lib/Win32.pod
index b2a4ac6eca..d0a62633e6 100644
--- a/lib/Win32.pod
+++ b/lib/Win32.pod
@@ -205,12 +205,12 @@ available drive letter.
=item Win32::GetOSVersion()
-[CORE] Returns the array (STRING, MAJOR, MINOR, BUILD, ID), where the
+[CORE] Returns the list (STRING, MAJOR, MINOR, BUILD, ID), where the
elements are, respectively: An arbitrary descriptive string, the major
version number of the operating system, the minor version number, the
build number, and a digit indicating the actual operating system.
-For the ID, the values are 0 for Win32s, 1 for Windows 9X and 2 for
-Windows NT/2000/XP. In scalar context it returns just the ID.
+For the ID, the values are 0 for Win32s, 1 for Windows 9X/Me and 2 for
+Windows NT/2000/XP/2003. In scalar context it returns just the ID.
Currently known values for ID MAJOR and MINOR are as follows:
@@ -223,10 +223,41 @@ Currently known values for ID MAJOR and MINOR are as follows:
Windows NT 4 2 4 0
Windows 2000 2 5 0
Windows XP 2 5 1
- Windows .NET Server 2 5 1
-
-Unfortunately as of June 2002 there is no way to distinguish between
-.NET servers and XP servers without using additional modules.
+ Windows Server 2003 2 5 2
+
+On Windows NT 4 SP6 and later this function returns the following
+additional values: SPMAJOR, SPMINOR, SUITEMASK, PRODUCTTYPE.
+
+SPMAJOR and SPMINOR are are the version numbers of the latest
+installed service pack.
+
+SUITEMASK is a bitfield identifying the product suites available on
+the system. Known bits are:
+
+ VER_SUITE_SMALLBUSINESS 0x00000001
+ VER_SUITE_ENTERPRISE 0x00000002
+ VER_SUITE_BACKOFFICE 0x00000004
+ VER_SUITE_COMMUNICATIONS 0x00000008
+ VER_SUITE_TERMINAL 0x00000010
+ VER_SUITE_SMALLBUSINESS_RESTRICTED 0x00000020
+ VER_SUITE_EMBEDDEDNT 0x00000040
+ VER_SUITE_DATACENTER 0x00000080
+ VER_SUITE_SINGLEUSERTS 0x00000100
+ VER_SUITE_PERSONAL 0x00000200
+ VER_SUITE_BLADE 0x00000400
+ VER_SUITE_EMBEDDED_RESTRICTED 0x00000800
+ VER_SUITE_SECURITY_APPLIANCE 0x00001000
+
+The VER_SUITE_xxx names are listed here to crossreference the Microsoft
+documentation. The Win32 module does not provide symbolic names for these
+constants.
+
+PRODUCTTYPE provides additional information about the system. It should
+be one of the following integer values:
+
+ 1 - Workstation (NT 4, 2000 Pro, XP Home, XP Pro)
+ 2 - Domaincontroller
+ 3 - Server
=item Win32::GetOSName()
@@ -239,7 +270,7 @@ GetOSVersion() in list context.
Currently the possible values for the OS name are
- Win32s Win95 Win98 WinMe Win2000 WinXP/.Net WinNT3.51 WinNT4
+ Win32s Win95 Win98 WinMe WinNT3.51 WinNT4 Win2000 WinXP/.Net Win2003
This routine is just a simple interface into GetOSVersion(). More
specific or demanding situations should use that instead. Another
@@ -247,6 +278,11 @@ option would be to use POSIX::uname(), however the latter appears to
report only the OS family name and not the specific OS. In scalar
context it returns just the ID.
+The name "WinXP/.Net" is used for historical reasons only, to maintain
+backwards compatibility of the Win32 module. Windows .NET Server has
+been renamed as Windows 2003 Server before final release and uses a
+different major/minor version number than Windows XP.
+
=item Win32::GetShortPathName(PATHNAME)
[CORE] Returns a representation of PATHNAME composed only of
diff --git a/win32/win32.c b/win32/win32.c
index c41c36d7ed..beabef6b02 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -4502,26 +4502,68 @@ static
XS(w32_GetOSVersion)
{
dXSARGS;
- OSVERSIONINFOA osver;
+ /* Use explicit struct definition because wSuiteMask and
+ * wProductType are not defined in the VC++ 6.0 headers.
+ * WORD type has been replaced by unsigned short because
+ * WORD is already used by Perl itself.
+ */
+ struct {
+ DWORD dwOSVersionInfoSize;
+ DWORD dwMajorVersion;
+ DWORD dwMinorVersion;
+ DWORD dwBuildNumber;
+ DWORD dwPlatformId;
+ CHAR szCSDVersion[128];
+ unsigned short wServicePackMajor;
+ unsigned short wServicePackMinor;
+ unsigned short wSuiteMask;
+ BYTE wProductType;
+ BYTE wReserved;
+ } osver;
+ BOOL bEx = TRUE;
if (USING_WIDE()) {
- OSVERSIONINFOW osverw;
+ struct {
+ DWORD dwOSVersionInfoSize;
+ DWORD dwMajorVersion;
+ DWORD dwMinorVersion;
+ DWORD dwBuildNumber;
+ DWORD dwPlatformId;
+ WCHAR szCSDVersion[128];
+ unsigned short wServicePackMajor;
+ unsigned short wServicePackMinor;
+ unsigned short wSuiteMask;
+ BYTE wProductType;
+ BYTE wReserved;
+ } osverw;
char szCSDVersion[sizeof(osverw.szCSDVersion)];
- osverw.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
- if (!GetVersionExW(&osverw)) {
- XSRETURN_EMPTY;
+ osverw.dwOSVersionInfoSize = sizeof(osverw);
+ if (!GetVersionExW((OSVERSIONINFOW*)&osverw)) {
+ bEx = FALSE;
+ osverw.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
+ if (!GetVersionExW((OSVERSIONINFOW*)&osverw)) {
+ XSRETURN_EMPTY;
+ }
}
W2AHELPER(osverw.szCSDVersion, szCSDVersion, sizeof(szCSDVersion));
XPUSHs(newSVpvn(szCSDVersion, strlen(szCSDVersion)));
- osver.dwMajorVersion = osverw.dwMajorVersion;
- osver.dwMinorVersion = osverw.dwMinorVersion;
- osver.dwBuildNumber = osverw.dwBuildNumber;
- osver.dwPlatformId = osverw.dwPlatformId;
+ osver.dwMajorVersion = osverw.dwMajorVersion;
+ osver.dwMinorVersion = osverw.dwMinorVersion;
+ osver.dwBuildNumber = osverw.dwBuildNumber;
+ osver.dwPlatformId = osverw.dwPlatformId;
+ osver.wServicePackMajor = osverw.wServicePackMajor;
+ osver.wServicePackMinor = osverw.wServicePackMinor;
+ osver.wSuiteMask = osverw.wSuiteMask;
+ osver.wProductType = osverw.wProductType;
}
else {
- osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
- if (!GetVersionExA(&osver)) {
- XSRETURN_EMPTY;
+ osver.dwOSVersionInfoSize = sizeof(osver);
+ if (!GetVersionExA((OSVERSIONINFOA*)&osver)) {
+ bEx = FALSE;
+ osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
+ if (!GetVersionExA((OSVERSIONINFOA*)&osver)) {
+ XSRETURN_EMPTY;
+ }
}
XPUSHs(newSVpvn(osver.szCSDVersion, strlen(osver.szCSDVersion)));
}
@@ -4529,6 +4571,12 @@ XS(w32_GetOSVersion)
XPUSHs(newSViv(osver.dwMinorVersion));
XPUSHs(newSViv(osver.dwBuildNumber));
XPUSHs(newSViv(osver.dwPlatformId));
+ if (bEx) {
+ XPUSHs(newSViv(osver.wServicePackMajor));
+ XPUSHs(newSViv(osver.wServicePackMinor));
+ XPUSHs(newSViv(osver.wSuiteMask));
+ XPUSHs(newSViv(osver.wProductType));
+ }
PUTBACK;
}