php_uname improvement on windows

[email protected] (Stanislav Malyshev)
Newsgroups php.internals.win
Organization Zend Technologies
Message-ID <[email protected]>
Hi!

I've wrote some patch improving php_uname output on Windows, so instead of:
Windows NT COMNAME 5.1 build 2600
we get:
Windows NT COMPNAME 5.1 build 2600 (Windows XP Professional Service Pack 
3) i586

Which could be very useful for some tasks. It uses a lot of defines 
though, so I'd be feeling bettr if somebody could check that it builds 
on all compiles/SDKs we use for windows builds. The .h file goes into 
ext\standard too.

Any comments?
-- 
Stanislav Malyshev, Zend Software Architect
[email protected]   http://www.zend.com/
(408)253-8829   MSN: [email protected]
winver.h (text/plain, 3.2 KB)
#ifndef _PHP_WINVER_H
#define _PHP_WINVER_H

#ifndef SM_SERVERR2
#define SM_SERVERR2 89
#endif
#ifndef VER_SUITE_WH_SERVER
#define VER_SUITE_WH_SERVER 0x8000
#endif

#ifndef PRODUCT_ULTIMATE
#define PRODUCT_UNDEFINED                       0x00000000
#define PRODUCT_ULTIMATE                        0x00000001
#define PRODUCT_HOME_BASIC                      0x00000002
#define PRODUCT_HOME_PREMIUM                    0x00000003
#define PRODUCT_ENTERPRISE                      0x00000004
#define PRODUCT_HOME_BASIC_N                    0x00000005
#define PRODUCT_BUSINESS                        0x00000006
#define PRODUCT_STANDARD_SERVER                 0x00000007
#define PRODUCT_DATACENTER_SERVER               0x00000008
#define PRODUCT_SMALLBUSINESS_SERVER            0x00000009
#define PRODUCT_ENTERPRISE_SERVER               0x0000000A
#define PRODUCT_STARTER                         0x0000000B
#define PRODUCT_DATACENTER_SERVER_CORE          0x0000000C
#define PRODUCT_STANDARD_SERVER_CORE            0x0000000D
#define PRODUCT_ENTERPRISE_SERVER_CORE          0x0000000E
#define PRODUCT_ENTERPRISE_SERVER_IA64          0x0000000F
#define PRODUCT_BUSINESS_N                      0x00000010
#define PRODUCT_WEB_SERVER                      0x00000011
#define PRODUCT_CLUSTER_SERVER                  0x00000012
#define PRODUCT_HOME_SERVER                     0x00000013
#define PRODUCT_STORAGE_EXPRESS_SERVER          0x00000014
#define PRODUCT_STORAGE_STANDARD_SERVER         0x00000015
#define PRODUCT_STORAGE_WORKGROUP_SERVER        0x00000016
#define PRODUCT_STORAGE_ENTERPRISE_SERVER       0x00000017
#define PRODUCT_SERVER_FOR_SMALLBUSINESS        0x00000018
#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM    0x00000019
#endif

#ifndef VER_NT_WORKSTATION
#define VER_NT_WORKSTATION              0x0000001
#define VER_NT_DOMAIN_CONTROLLER        0x0000002
#define VER_NT_SERVER                   0x0000003
#endif

#ifndef VER_SUITE_SMALLBUSINESS
#define VER_SUITE_SMALLBUSINESS             0x00000001
#define VER_SUITE_ENTERPRISE                0x00000002
#define VER_SUITE_BACKOFFICE                0x00000004
#define VER_SUITE_COMMUNICATIONS            0x00000008
#define VER_SUITE_TERMINAL                  0x00000010
#define VER_SUITE_SMALLBUSINESS_RESTRICTED  0x00000020
#define VER_SUITE_EMBEDDEDNT                0x00000040
#define VER_SUITE_DATACENTER                0x00000080
#define VER_SUITE_SINGLEUSERTS              0x00000100
#define VER_SUITE_PERSONAL                  0x00000200
#define VER_SUITE_BLADE                     0x00000400
#define VER_SUITE_EMBEDDED_RESTRICTED       0x00000800
#define VER_SUITE_SECURITY_APPLIANCE        0x00001000
#define VER_SUITE_STORAGE_SERVER            0x00002000
#define VER_SUITE_COMPUTE_SERVER            0x00004000
#endif

#ifndef PROCESSOR_ARCHITECTURE_AMD64
#define PROCESSOR_ARCHITECTURE_AMD64            9
#endif

typedef struct _php_win_OSVERSIONINFOEXA {
    DWORD dwOSVersionInfoSize;
    DWORD dwMajorVersion;
    DWORD dwMinorVersion;
    DWORD dwBuildNumber;
    DWORD dwPlatformId;
    CHAR  szCSDVersion[128];     
    WORD  wServicePackMajor;
    WORD  wServicePackMinor;
    WORD  wSuiteMask;
    BYTE  wProductType;
    BYTE  wReserved;
} php_win_OSVERSIONINFOEX;

#endif
info.diff (text/plain, 9.4 KB)
Index: info.c
===================================================================
RCS file: /repository/php-src/ext/standard/info.c,v
retrieving revision 1.249.2.10.2.14.2.13
diff -u -r1.249.2.10.2.14.2.13 info.c
--- info.c	21 Oct 2008 22:08:37 -0000	1.249.2.10.2.14.2.13
+++ info.c	5 Dec 2008 02:00:59 -0000
@@ -238,6 +238,220 @@
 /* }}} */
 
 
+#ifdef PHP_WIN32
+/* {{{  */
+typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
+typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);
+
+#include "winver.h"
+
+#if _MSC_VER < 1300
+#define OSVERSIONINFOEX php_win_OSVERSIONINFOEX
+#endif
+
+char* php_get_windows_name()
+{
+	OSVERSIONINFOEX osvi;
+	SYSTEM_INFO si;
+	PGNSI pGNSI;
+	PGPI pGPI;
+	BOOL bOsVersionInfoEx;
+	DWORD dwType;
+	char *major = NULL, *sub = NULL, *retval;
+
+	ZeroMemory(&si, sizeof(SYSTEM_INFO));
+	ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+
+	if (!(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi))) {
+		return NULL;
+	}
+
+	pGNSI = (PGNSI) GetProcAddress(GetModuleHandle("kernel32.dll"), "GetNativeSystemInfo");
+	if(NULL != pGNSI) {
+		pGNSI(&si);
+	} else {
+		GetSystemInfo(&si);
+	}
+
+	if (VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion > 4 ) {
+		if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0 )	{
+			if (osvi.wProductType == VER_NT_WORKSTATION) {
+				major = "Windows Vista";
+			} else {
+				major = "Windows Server 2008";
+			}
+
+			pGPI = (PGPI) GetProcAddress(GetModuleHandle("kernel32.dll"), "GetProductInfo");
+			pGPI(6, 0, 0, 0, &dwType);
+
+			switch (dwType) {
+				case PRODUCT_ULTIMATE:
+					sub = "Ultimate Edition";
+					break;
+				case PRODUCT_HOME_PREMIUM:
+					sub = "Home Premium Edition";
+					break;
+				case PRODUCT_HOME_BASIC:
+					sub = "Home Basic Edition";
+					break;
+				case PRODUCT_ENTERPRISE:
+					sub = "Enterprise Edition";
+					break;
+				case PRODUCT_BUSINESS:
+					sub = "Business Edition";
+					break;
+				case PRODUCT_STARTER:
+					sub = "Starter Edition";
+					break;
+				case PRODUCT_CLUSTER_SERVER:
+					sub = "Cluster Server Edition";
+					break;
+				case PRODUCT_DATACENTER_SERVER:
+					sub = "Datacenter Edition";
+					break;
+				case PRODUCT_DATACENTER_SERVER_CORE:
+					sub = "Datacenter Edition (core installation)";
+					break;
+				case PRODUCT_ENTERPRISE_SERVER:
+					sub = "Enterprise Edition";
+					break;
+				case PRODUCT_ENTERPRISE_SERVER_CORE:
+					sub = "Enterprise Edition (core installation)";
+					break;
+				case PRODUCT_ENTERPRISE_SERVER_IA64:
+					sub = "Enterprise Edition for Itanium-based Systems";
+					break;
+				case PRODUCT_SMALLBUSINESS_SERVER:
+					sub = "Small Business Server";
+					break;
+				case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
+					sub = "Small Business Server Premium Edition";
+					break;
+				case PRODUCT_STANDARD_SERVER:
+					sub = "Standard Edition";
+					break;
+				case PRODUCT_STANDARD_SERVER_CORE:
+					sub = "Standard Edition (core installation)";
+					break;
+				case PRODUCT_WEB_SERVER:
+					sub = "Web Server Edition";
+					break;
+			}
+		}
+
+		if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )	{
+			if (GetSystemMetrics(SM_SERVERR2))
+				major = "Windows Server 2003 R2";
+			else if (osvi.wSuiteMask==VER_SUITE_STORAGE_SERVER)
+				major = "Windows Storage Server 2003";
+			else if (osvi.wSuiteMask==VER_SUITE_WH_SERVER)
+				major = "Windows Home Server";
+			else if (osvi.wProductType == VER_NT_WORKSTATION &&
+				si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) {
+				major = "Windows XP Professional x64 Edition";
+			} else {
+				major = "Windows Server 2003";
+			}
+
+			/* Test for the server type. */
+			if ( osvi.wProductType != VER_NT_WORKSTATION ) {
+				if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64 ) {
+					if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
+						sub = "Datacenter Edition for Itanium-based Systems";
+					else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
+						sub = "Enterprise Edition for Itanium-based Systems";
+				}
+
+				else if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 ) {
+					if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
+						sub = "Datacenter x64 Edition";
+					else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
+						sub = "Enterprise x64 Edition";
+					else sub = "Standard x64 Edition";
+				} else {
+					if ( osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER )
+						sub = "Compute Cluster Edition";
+					else if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
+						sub = "Datacenter Edition";
+					else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
+						sub = "Enterprise Edition";
+					else if ( osvi.wSuiteMask & VER_SUITE_BLADE )
+						sub = "Web Edition";
+					else sub = "Standard Edition";
+				}
+			} 
+		}
+
+		if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )	{
+			major = "Windows XP";
+			if( osvi.wSuiteMask & VER_SUITE_PERSONAL )
+				sub = "Home Edition";
+			else sub = "Professional";
+		}
+
+		if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 ) {
+			major = "Windows 2000";
+
+			if (osvi.wProductType == VER_NT_WORKSTATION ) {
+				sub = "Professional";
+			} else {
+				if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
+					sub = "Datacenter Server";
+				else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
+					sub = "Advanced Server";
+				else sub = "Server";
+			}
+		}
+	} else {
+		return NULL;
+	}
+
+	spprintf(&retval, 0, "%s%s%s%s%s", major, sub?" ":"", sub?sub:"", osvi.szCSDVersion[0] != '\0'?" ":"", osvi.szCSDVersion);
+	return retval;
+}
+/* }}}  */
+
+/* {{{  */
+void php_get_windows_cpu(char *buf, int bufsize)
+{
+	SYSTEM_INFO SysInfo;
+	GetSystemInfo(&SysInfo);
+	switch (SysInfo.wProcessorArchitecture) {
+		case PROCESSOR_ARCHITECTURE_INTEL :
+			snprintf(buf, bufsize, "i%d", SysInfo.dwProcessorType);
+			break;
+		case PROCESSOR_ARCHITECTURE_MIPS :
+			snprintf(buf, bufsize, "MIPS R%d000", SysInfo.wProcessorLevel);
+			break;
+		case PROCESSOR_ARCHITECTURE_ALPHA :
+			snprintf(buf, bufsize, "Alpha %d", SysInfo.wProcessorLevel);
+			break;
+		case PROCESSOR_ARCHITECTURE_PPC :
+			snprintf(buf, bufsize, "PPC 6%02d", SysInfo.wProcessorLevel);
+			break;
+		case PROCESSOR_ARCHITECTURE_IA64 :
+			snprintf(buf, bufsize,  "IA64");
+			break;
+#if defined(PROCESSOR_ARCHITECTURE_IA32_ON_WIN64)
+		case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 :
+			snprintf(buf, bufsize, "IA32");
+			break;
+#endif
+#if defined(PROCESSOR_ARCHITECTURE_AMD64)
+		case PROCESSOR_ARCHITECTURE_AMD64 :
+			snprintf(buf, bufsize, "AMD64");
+			break;
+#endif
+		case PROCESSOR_ARCHITECTURE_UNKNOWN :
+		default:
+			snprintf(buf, bufsize, "Unknown");
+			break;
+	}
+}
+/* }}}  */
+#endif
+
 /* {{{ php_get_uname
  */
 PHPAPI char *php_get_uname(char mode)
@@ -251,10 +465,8 @@
 	DWORD dwWindowsMinorVersion =  (DWORD)(HIBYTE(LOWORD(dwVersion)));
 	DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
 	char ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
-	SYSTEM_INFO SysInfo;
-
+	
 	GetComputerName(ComputerName, &dwSize);
-	GetSystemInfo(&SysInfo);
 
 	if (mode == 's') {
 		if (dwVersion < 0x80000000) {
@@ -268,52 +480,34 @@
 	} else if (mode == 'n') {
 		php_uname = ComputerName;
 	} else if (mode == 'v') {
+		char *winver = php_get_windows_name();
 		dwBuild = (DWORD)(HIWORD(dwVersion));
-		snprintf(tmp_uname, sizeof(tmp_uname), "build %d", dwBuild);
+		if(winver == NULL) {
+			snprintf(tmp_uname, sizeof(tmp_uname), "build %d", dwBuild);
+		} else {
+			snprintf(tmp_uname, sizeof(tmp_uname), "build %d (%s)", dwBuild, winver);
+		}
 		php_uname = tmp_uname;
-	} else if (mode == 'm') {
-		switch (SysInfo.wProcessorArchitecture) {
-			case PROCESSOR_ARCHITECTURE_INTEL :
-				snprintf(tmp_uname, sizeof(tmp_uname), "i%d", SysInfo.dwProcessorType);
-				php_uname = tmp_uname;
-				break;
-			case PROCESSOR_ARCHITECTURE_MIPS :
-				snprintf(tmp_uname, sizeof(tmp_uname), "MIPS R%d000", SysInfo.wProcessorLevel);
-				php_uname = tmp_uname;
-				break;
-			case PROCESSOR_ARCHITECTURE_ALPHA :
-				snprintf(tmp_uname, sizeof(tmp_uname), "Alpha %d", SysInfo.wProcessorLevel);
-				php_uname = tmp_uname;
-				break;
-			case PROCESSOR_ARCHITECTURE_PPC :
-				snprintf(tmp_uname, sizeof(tmp_uname), "PPC 6%02d", SysInfo.wProcessorLevel);
-				php_uname = tmp_uname;
-				break;
-			case PROCESSOR_ARCHITECTURE_IA64 :
-				php_uname = "IA64";
-				break;
-#if defined(PROCESSOR_ARCHITECTURE_IA32_ON_WIN64)
-			case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 :
-				php_uname = "IA32";
-				break;
-#endif
-#if defined(PROCESSOR_ARCHITECTURE_AMD64)
-			case PROCESSOR_ARCHITECTURE_AMD64 :
-				php_uname = "AMD64";
-				break;
-#endif
-			case PROCESSOR_ARCHITECTURE_UNKNOWN :
-			default :
-				php_uname = "Unknown";
-				break;
+		if(winver) {
+			efree(winver);
 		}
+	} else if (mode == 'm') {
+		php_get_windows_cpu(tmp_uname, sizeof(tmp_uname));
+		php_uname = tmp_uname;
 	} else { /* assume mode == 'a' */
 		/* Get build numbers for Windows NT or Win95 */
 		if (dwVersion < 0x80000000){
+			char *winver = php_get_windows_name();
+			char wincpu[20];
+
+			php_get_windows_cpu(wincpu, sizeof(wincpu));
 			dwBuild = (DWORD)(HIWORD(dwVersion));
-			snprintf(tmp_uname, sizeof(tmp_uname), "%s %s %d.%d build %d",
+			snprintf(tmp_uname, sizeof(tmp_uname), "%s %s %d.%d build %d (%s) %s",
 					 "Windows NT", ComputerName,
-					 dwWindowsMajorVersion, dwWindowsMinorVersion, dwBuild);
+					 dwWindowsMajorVersion, dwWindowsMinorVersion, dwBuild, winver?winver:"unknown", wincpu);
+			if(winver) {
+				efree(winver);
+			}
 		} else {
 			snprintf(tmp_uname, sizeof(tmp_uname), "%s %s %d.%d",
 					 "Windows 9x", ComputerName,
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.