1 /**
2  * \file   os_getversioninfo.c
3  * \brief  Retrieve operating system version information.
4  * \author Copyright (c) 2011-2012 Jason Perkins and the Premake project
5  */
6 
7 #include "premake.h"
8 #include <stdlib.h>
9 
10 struct OsVersionInfo
11 {
12 	int majorversion;
13 	int minorversion;
14 	int revision;
15 	const char* description;
16 	int isalloc;
17 };
18 
19 static void getversion(struct OsVersionInfo* info);
20 
21 
os_getversion(lua_State * L)22 int os_getversion(lua_State* L)
23 {
24 	struct OsVersionInfo info = {0};
25 	getversion(&info);
26 
27 	lua_newtable(L);
28 
29 	lua_pushstring(L, "majorversion");
30 	lua_pushnumber(L, info.majorversion);
31 	lua_settable(L, -3);
32 
33 	lua_pushstring(L, "minorversion");
34 	lua_pushnumber(L, info.minorversion);
35 	lua_settable(L, -3);
36 
37 	lua_pushstring(L, "revision");
38 	lua_pushnumber(L, info.revision);
39 	lua_settable(L, -3);
40 
41 	lua_pushstring(L, "description");
42 	lua_pushstring(L, info.description);
43 	lua_settable(L, -3);
44 
45 	if (info.isalloc) {
46 		free((void*)info.description);
47 	}
48 
49 	return 1;
50 }
51 
52 /*************************************************************/
53 
54 #if defined(PLATFORM_WINDOWS)
55 
56 #if !defined(VER_SUITE_WH_SERVER)
57 #define VER_SUITE_WH_SERVER   (0x00008000)
58 #endif
59 
60 #ifndef SM_SERVERR2
61 #	define SM_SERVERR2 89
62 #endif
63 
getsysteminfo()64 SYSTEM_INFO getsysteminfo()
65 {
66 	typedef void (WINAPI *GetNativeSystemInfoSig)(LPSYSTEM_INFO);
67 	GetNativeSystemInfoSig nativeSystemInfo = (GetNativeSystemInfoSig)
68 	GetProcAddress(GetModuleHandle(TEXT("kernel32")), "GetNativeSystemInfo");
69 
70 	SYSTEM_INFO systemInfo = {{0}};
71 	if ( nativeSystemInfo ) nativeSystemInfo(&systemInfo);
72 	else GetSystemInfo(&systemInfo);
73 	return systemInfo;
74 }
75 
getversion(struct OsVersionInfo * info)76 void getversion(struct OsVersionInfo* info)
77 {
78 	OSVERSIONINFOEX versionInfo = {0};
79 
80 	versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
81 	GetVersionEx((OSVERSIONINFO*)&versionInfo);
82 
83 	info->majorversion = versionInfo.dwMajorVersion;
84 	info->minorversion = versionInfo.dwMinorVersion;
85 	info->revision = versionInfo.wServicePackMajor;
86 
87 	if (versionInfo.dwMajorVersion == 5 && versionInfo.dwMinorVersion == 0)
88 	{
89 		info->description = "Windows 2000";
90 	}
91 	else if (versionInfo.dwMajorVersion == 5 && versionInfo.dwMinorVersion == 1)
92 	{
93 		info->description = "Windows XP";
94 	}
95 	else if (versionInfo.dwMajorVersion == 5 && versionInfo.dwMinorVersion == 2)
96 	{
97 		SYSTEM_INFO systemInfo = getsysteminfo();
98 		if (versionInfo.wProductType == VER_NT_WORKSTATION &&
99 			systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
100 		{
101 			info->description = "Windows XP Professional x64";
102 		}
103 		else if (versionInfo.wSuiteMask & VER_SUITE_WH_SERVER)
104 		{
105 			info->description = "Windows Home Server";
106 		}
107 		else if (GetSystemMetrics(SM_SERVERR2) == 0)
108 		{
109 			info->description = "Windows Server 2003";
110 		}
111 		else
112 		{
113 			info->description = "Windows Server 2003 R2";
114 		}
115 	}
116 	else if (versionInfo.dwMajorVersion == 6 && versionInfo.dwMinorVersion == 0)
117 	{
118 		if (versionInfo.wProductType == VER_NT_WORKSTATION)
119 		{
120 			info->description = "Windows Vista";
121 		}
122 		else
123 		{
124 			info->description = "Windows Server 2008";
125 		}
126 	}
127 	else if (versionInfo.dwMajorVersion == 6 && versionInfo.dwMinorVersion == 1 )
128 	{
129 		if (versionInfo.wProductType != VER_NT_WORKSTATION)
130 		{
131 			info->description = "Windows Server 2008 R2";
132 		}
133 		else
134 		{
135 			info->description = "Windows 7";
136 		}
137 	}
138 	else
139 	{
140 		info->description = "Windows";
141 	}
142 }
143 
144 /*************************************************************/
145 
146 #elif defined(PLATFORM_MACOSX)
147 
148 #include <CoreServices/CoreServices.h>
149 
getversion(struct OsVersionInfo * info)150 void getversion(struct OsVersionInfo* info)
151 {
152 	SInt32 majorversion, minorversion, bugfix;
153 	Gestalt(gestaltSystemVersionMajor, &majorversion);
154 	Gestalt(gestaltSystemVersionMinor, &minorversion);
155 	Gestalt(gestaltSystemVersionBugFix, &bugfix);
156 
157 	info->majorversion = majorversion;
158 	info->minorversion = minorversion;
159 	info->revision = bugfix;
160 
161 	info->description = "Mac OS X";
162 	if (info->majorversion == 10)
163 	{
164 		switch (info->minorversion)
165 		{
166 		case 4:
167 			info->description = "Mac OS X Tiger";
168 			break;
169 		case 5:
170 			info->description = "Mac OS X Leopard";
171 			break;
172 		case 6:
173 			info->description = "Mac OS X Snow Leopard";
174 			break;
175 		case 7:
176 			info->description = "Mac OS X Lion";
177 			break;
178 		}
179 	}
180 }
181 
182 /*************************************************************/
183 
184 #elif defined(PLATFORM_BSD) || defined(PLATFORM_LINUX) || defined(PLATFORM_SOLARIS)
185 
186 #include <string.h>
187 #include <sys/utsname.h>
188 
getversion(struct OsVersionInfo * info)189 void getversion(struct OsVersionInfo* info)
190 {
191 	struct utsname u;
192 	char* ver;
193 
194 	info->majorversion = 0;
195 	info->minorversion = 0;
196 	info->revision = 0;
197 
198 	if (uname(&u))
199 	{
200 		// error
201 		info->description = PLATFORM_STRING;
202 		return;
203 	}
204 
205 #if __GLIBC__
206 	// When using glibc, info->description gets set to u.sysname,
207 	// but it isn't passed out of this function, so we need to copy
208 	// the string.
209 	info->description = malloc(strlen(u.sysname) + 1);
210 	strcpy((char*)info->description, u.sysname);
211 	info->isalloc = 1;
212 #else
213 	info->description = u.sysname;
214 #endif
215 
216 	if ((ver = strtok(u.release, ".-")) != NULL)
217 	{
218 		info->majorversion = atoi(ver);
219 		// continue parsing from the previous position
220 		if ((ver = strtok(NULL, ".-")) != NULL)
221 		{
222 			info->minorversion = atoi(ver);
223 			if ((ver = strtok(NULL, ".-")) != NULL)
224 				info->revision = atoi(ver);
225 		}
226 	}
227 }
228 
229 /*************************************************************/
230 
231 #else
232 
getversion(struct OsVersionInfo * info)233 void getversion(struct OsVersionInfo* info)
234 {
235 	info->majorversion = 0;
236 	info->minorversion = 0;
237 	info->revision = 0;
238 	info->description = PLATFORM_STRING;
239 }
240 
241 #endif
242 
243