2 Copyright (C) 2009-2020 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
20 #include <sys/utsname.h>
22 /* This file provides an implementation only for the native Windows API. */
23 #if defined _WIN32 && ! defined __CYGWIN__
31 /* Mingw headers don't have all the platform codes. */
32 # ifndef VER_PLATFORM_WIN32_CE
33 # define VER_PLATFORM_WIN32_CE 3
36 /* Some headers don't have all the processor architecture codes. */
37 # ifndef PROCESSOR_ARCHITECTURE_AMD64
38 # define PROCESSOR_ARCHITECTURE_AMD64 9
40 # ifndef PROCESSOR_ARCHITECTURE_IA32_ON_WIN64
41 # define PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 10
44 /* Mingw headers don't have the latest processor codes. */
45 # ifndef PROCESSOR_AMD_X8664
46 # define PROCESSOR_AMD_X8664 8664
49 /* Don't assume that UNICODE is not defined. */
51 # define OSVERSIONINFO OSVERSIONINFOA
53 # define GetVersionEx GetVersionExA
56 uname (struct utsname
*buf
)
58 OSVERSIONINFO version
;
59 OSVERSIONINFOEX versionex
;
60 BOOL have_versionex
; /* indicates whether versionex is filled */
61 const char *super_version
;
63 /* Preparation: Fill version and, if possible, also versionex.
64 But try to call GetVersionEx only once in the common case. */
65 versionex
.dwOSVersionInfoSize
= sizeof (OSVERSIONINFOEX
);
66 have_versionex
= GetVersionEx ((OSVERSIONINFO
*) &versionex
);
69 /* We know that OSVERSIONINFO is a subset of OSVERSIONINFOEX. */
70 memcpy (&version
, &versionex
, sizeof (OSVERSIONINFO
));
74 version
.dwOSVersionInfoSize
= sizeof (OSVERSIONINFO
);
75 if (!GetVersionEx (&version
))
79 /* Fill in nodename. */
80 if (gethostname (buf
->nodename
, sizeof (buf
->nodename
)) < 0)
81 strcpy (buf
->nodename
, "localhost");
83 /* Determine major-major Windows version. */
84 if (version
.dwPlatformId
== VER_PLATFORM_WIN32_NT
)
86 /* Windows NT or newer. */
89 else if (version
.dwPlatformId
== VER_PLATFORM_WIN32_CE
)
91 /* Windows CE or Embedded CE. */
94 else if (version
.dwPlatformId
== VER_PLATFORM_WIN32_WINDOWS
)
96 /* Windows 95/98/ME. */
97 switch (version
.dwMinorVersion
)
100 super_version
= "95";
103 super_version
= "98";
106 super_version
= "ME";
116 /* Fill in sysname. */
118 /* Returns a string compatible with the MSYS uname.exe program,
119 so that no further changes are needed to GNU config.guess.
121 $ ./uname.exe -s => MINGW32_NT-5.1
123 sprintf (buf
->sysname
, "MINGW32_%s-%u.%u", super_version
,
124 (unsigned int) version
.dwMajorVersion
,
125 (unsigned int) version
.dwMinorVersion
);
127 sprintf (buf
->sysname
, "Windows%s", super_version
);
130 /* Fill in release, version. */
131 /* The MSYS uname.exe programs uses strings from a modified Cygwin runtime:
132 $ ./uname.exe -r => 1.0.11(0.46/3/2)
133 $ ./uname.exe -v => 2008-08-25 23:40
134 There is no point in imitating this behaviour. */
135 if (version
.dwPlatformId
== VER_PLATFORM_WIN32_NT
)
137 /* Windows NT or newer. */
138 struct windows_version
142 unsigned int server_offset
;
146 /* Storing the workstation and server version names in a single
147 stream does not waste memory when they are the same. These
148 macros abstract the representation. VERSION1 is used if
149 version.wProductType does not matter, VERSION2 if it does. */
150 #define VERSION1(major, minor, name) \
151 { major, minor, 0, name }
152 #define VERSION2(major, minor, workstation, server) \
153 { major, minor, sizeof workstation, workstation "\0" server }
154 static const struct windows_version versions
[] =
156 VERSION2 (3, -1, "Windows NT Workstation", "Windows NT Server"),
157 VERSION2 (4, -1, "Windows NT Workstation", "Windows NT Server"),
158 VERSION1 (5, 0, "Windows 2000"),
159 VERSION1 (5, 1, "Windows XP"),
160 VERSION1 (5, 2, "Windows Server 2003"),
161 VERSION2 (6, 0, "Windows Vista", "Windows Server 2008"),
162 VERSION2 (6, 1, "Windows 7", "Windows Server 2008 R2"),
163 VERSION2 (-1, -1, "Windows", "Windows Server")
166 const struct windows_version
*v
= versions
;
168 /* Find a version that matches ours. The last element is a
169 wildcard that always ends the loop. */
170 while ((v
->major
!= version
.dwMajorVersion
&& v
->major
!= -1)
171 || (v
->minor
!= version
.dwMinorVersion
&& v
->minor
!= -1))
174 if (have_versionex
&& versionex
.wProductType
!= VER_NT_WORKSTATION
)
175 base
= v
->name
+ v
->server_offset
;
178 if (v
->major
== -1 || v
->minor
== -1)
179 sprintf (buf
->release
, "%s %u.%u",
181 (unsigned int) version
.dwMajorVersion
,
182 (unsigned int) version
.dwMinorVersion
);
184 strcpy (buf
->release
, base
);
186 else if (version
.dwPlatformId
== VER_PLATFORM_WIN32_CE
)
188 /* Windows CE or Embedded CE. */
189 sprintf (buf
->release
, "Windows CE %u.%u",
190 (unsigned int) version
.dwMajorVersion
,
191 (unsigned int) version
.dwMinorVersion
);
195 /* Windows 95/98/ME. */
196 sprintf (buf
->release
, "Windows %s", super_version
);
198 strcpy (buf
->version
, version
.szCSDVersion
);
200 /* Fill in machine. */
204 GetSystemInfo (&info
);
205 /* Check for Windows NT or CE, since the info.wProcessorLevel is
206 garbage on Windows 95. */
207 if (version
.dwPlatformId
== VER_PLATFORM_WIN32_NT
208 || version
.dwPlatformId
== VER_PLATFORM_WIN32_CE
)
210 /* Windows NT or newer, or Windows CE or Embedded CE. */
211 switch (info
.wProcessorArchitecture
)
213 case PROCESSOR_ARCHITECTURE_AMD64
:
214 strcpy (buf
->machine
, "x86_64");
216 case PROCESSOR_ARCHITECTURE_IA64
:
217 strcpy (buf
->machine
, "ia64");
219 case PROCESSOR_ARCHITECTURE_INTEL
:
220 strcpy (buf
->machine
, "i386");
221 if (info
.wProcessorLevel
>= 3)
223 '0' + (info
.wProcessorLevel
<= 6 ? info
.wProcessorLevel
: 6);
225 case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64
:
226 strcpy (buf
->machine
, "i686");
228 case PROCESSOR_ARCHITECTURE_MIPS
:
229 strcpy (buf
->machine
, "mips");
231 case PROCESSOR_ARCHITECTURE_ALPHA
:
232 case PROCESSOR_ARCHITECTURE_ALPHA64
:
233 strcpy (buf
->machine
, "alpha");
235 case PROCESSOR_ARCHITECTURE_PPC
:
236 strcpy (buf
->machine
, "powerpc");
238 case PROCESSOR_ARCHITECTURE_SHX
:
239 strcpy (buf
->machine
, "sh");
241 case PROCESSOR_ARCHITECTURE_ARM
:
242 strcpy (buf
->machine
, "arm");
245 strcpy (buf
->machine
, "unknown");
251 /* Windows 95/98/ME. */
252 switch (info
.dwProcessorType
)
254 case PROCESSOR_AMD_X8664
:
255 strcpy (buf
->machine
, "x86_64");
257 case PROCESSOR_INTEL_IA64
:
258 strcpy (buf
->machine
, "ia64");
261 if (info
.dwProcessorType
% 100 == 86)
262 sprintf (buf
->machine
, "i%u",
263 (unsigned int) info
.dwProcessorType
);
265 strcpy (buf
->machine
, "unknown");