2 * Windows version functions
4 * Copyright 1997 Alexandre Julliard
5 * Copyright 1997 Marcus Meissner
6 * Copyright 1998 Patrik Stridvall
16 #include "winversion.h"
22 OSVERSIONINFO32A getVersionEx;
26 /* FIXME: compare values below with original and fix */
27 static const VERSION_DATA VersionData[NB_WINDOWS_VERSIONS] =
31 MAKELONG( 0x0a03, 0x0616 ), /* DOS 6.22 */
32 MAKELONG( 0x0a03, 0x8000 ),
34 sizeof(OSVERSIONINFO32A), 3, 10, 0,
35 VER_PLATFORM_WIN32s, "Win32s 1.3"
43 sizeof(OSVERSIONINFO32A), 4, 0, 0x40003B6,
44 VER_PLATFORM_WIN32_WINDOWS, "Win95"
52 sizeof(OSVERSIONINFO32A), 3, 51, 0x421,
53 VER_PLATFORM_WIN32_NT, "Service Pack 2"
61 sizeof(OSVERSIONINFO32A), 4, 0, 0x565,
62 VER_PLATFORM_WIN32_NT, "Service Pack 3"
67 static const char *VersionNames[NB_WINDOWS_VERSIONS] =
75 /* the current version has not been autodetected but forced via cmdline */
76 static BOOL32 versionForced = FALSE;
77 static WINDOWS_VERSION defaultVersion = WIN31;
80 /**********************************************************************
81 * VERSION_ParseVersion
83 void VERSION_ParseVersion( char *arg )
86 for (i = 0; i < NB_WINDOWS_VERSIONS; i++)
88 if (!strcmp( VersionNames[i], arg ))
90 defaultVersion = (WINDOWS_VERSION)i;
95 MSG("Invalid winver value '%s' specified.\n", arg );
96 MSG("Valid versions are:" );
97 for (i = 0; i < NB_WINDOWS_VERSIONS; i++)
98 MSG(" '%s'%c", VersionNames[i],
99 (i == NB_WINDOWS_VERSIONS - 1) ? '\n' : ',' );
103 /**********************************************************************
106 WINDOWS_VERSION VERSION_GetVersion(void)
108 PIMAGE_NT_HEADERS peheader;
110 if (versionForced) /* user has overridden any sensible checks */
111 return defaultVersion;
112 if (!PROCESS_Current()->exe_modref)
114 /* HACK: if we have loaded a PE image into this address space,
115 * we are probably using thunks, so Win95 is our best bet
117 if (PROCESS_Current()->modref_list) return WIN95;
118 return WIN31; /* FIXME: hmm, look at DDB.version ? */
120 peheader = PE_HEADER(PROCESS_Current()->exe_modref->module);
121 if (peheader->OptionalHeader.MajorSubsystemVersion == 4) {
122 /* FIXME: check probably not 100% good, verify with win98 too */
123 if (peheader->OptionalHeader.MajorOperatingSystemVersion == 4)
127 if (peheader->OptionalHeader.MajorSubsystemVersion == 3)
130 if (peheader->OptionalHeader.MinorSubsystemVersion <= 11) return WIN31;
132 if (peheader->OptionalHeader.MinorSubsystemVersion == 50) return NT351;
133 if (peheader->OptionalHeader.MinorSubsystemVersion == 51) return NT351;
135 ERR(ver,"unknown subsystem version: %04x.%04x, please report.\n",
136 peheader->OptionalHeader.MajorSubsystemVersion,
137 peheader->OptionalHeader.MinorSubsystemVersion );
138 return defaultVersion;
142 /**********************************************************************
143 * VERSION_GetVersionName
145 char *VERSION_GetVersionName()
147 WINDOWS_VERSION ver = VERSION_GetVersion();
151 return "Windows 3.1";
155 return "Windows NT 3.51";
157 return "Windows NT 4.0";
159 FIXME(ver,"Windows version %d not named",ver);
160 return "Windows <Unknown>";
164 /***********************************************************************
165 * GetVersion16 (KERNEL.3)
167 LONG WINAPI GetVersion16(void)
169 WINDOWS_VERSION ver = VERSION_GetVersion();
170 return VersionData[ver].getVersion16;
174 /***********************************************************************
175 * GetVersion32 (KERNEL32.427)
177 LONG WINAPI GetVersion32(void)
179 WINDOWS_VERSION ver = VERSION_GetVersion();
180 return VersionData[ver].getVersion32;
184 /***********************************************************************
185 * GetVersionEx16 (KERNEL.149)
187 BOOL16 WINAPI GetVersionEx16(OSVERSIONINFO16 *v)
189 WINDOWS_VERSION ver = VERSION_GetVersion();
190 if (v->dwOSVersionInfoSize != sizeof(OSVERSIONINFO16))
192 WARN(ver,"wrong OSVERSIONINFO size from app");
195 v->dwMajorVersion = VersionData[ver].getVersionEx.dwMajorVersion;
196 v->dwMinorVersion = VersionData[ver].getVersionEx.dwMinorVersion;
197 v->dwBuildNumber = VersionData[ver].getVersionEx.dwBuildNumber;
198 v->dwPlatformId = VersionData[ver].getVersionEx.dwPlatformId;
199 strcpy( v->szCSDVersion, VersionData[ver].getVersionEx.szCSDVersion );
204 /***********************************************************************
205 * GetVersionEx32A (KERNEL32.428)
207 BOOL32 WINAPI GetVersionEx32A(OSVERSIONINFO32A *v)
209 WINDOWS_VERSION ver = VERSION_GetVersion();
210 if (v->dwOSVersionInfoSize != sizeof(OSVERSIONINFO32A))
212 WARN(ver,"wrong OSVERSIONINFO size from app");
215 v->dwMajorVersion = VersionData[ver].getVersionEx.dwMajorVersion;
216 v->dwMinorVersion = VersionData[ver].getVersionEx.dwMinorVersion;
217 v->dwBuildNumber = VersionData[ver].getVersionEx.dwBuildNumber;
218 v->dwPlatformId = VersionData[ver].getVersionEx.dwPlatformId;
219 strcpy( v->szCSDVersion, VersionData[ver].getVersionEx.szCSDVersion );
224 /***********************************************************************
225 * GetVersionEx32W (KERNEL32.429)
227 BOOL32 WINAPI GetVersionEx32W(OSVERSIONINFO32W *v)
229 WINDOWS_VERSION ver = VERSION_GetVersion();
231 if (v->dwOSVersionInfoSize!=sizeof(OSVERSIONINFO32W))
233 WARN(ver,"wrong OSVERSIONINFO size from app");
236 v->dwMajorVersion = VersionData[ver].getVersionEx.dwMajorVersion;
237 v->dwMinorVersion = VersionData[ver].getVersionEx.dwMinorVersion;
238 v->dwBuildNumber = VersionData[ver].getVersionEx.dwBuildNumber;
239 v->dwPlatformId = VersionData[ver].getVersionEx.dwPlatformId;
240 lstrcpyAtoW( v->szCSDVersion, VersionData[ver].getVersionEx.szCSDVersion );
245 /***********************************************************************
246 * GetWinFlags (KERNEL.132)
248 DWORD WINAPI GetWinFlags(void)
250 static const long cpuflags[5] =
251 { WF_CPU086, WF_CPU186, WF_CPU286, WF_CPU386, WF_CPU486 };
253 OSVERSIONINFO32A ovi;
258 /* There doesn't seem to be any Pentium flag. */
259 result = cpuflags[MIN (si.wProcessorLevel, 4)];
264 result |= WF_STANDARD | WF_PMODE | WF_80x87;
268 result |= WF_ENHANCED | WF_PMODE | WF_80x87 | WF_PAGING;
272 ERR(ver, "Unknown mode set? This shouldn't happen. Check GetWinFlags()!\n");
275 if (si.wProcessorLevel >= 4) result |= WF_HASCPUID;
276 ovi.dwOSVersionInfoSize = sizeof(ovi);
277 GetVersionEx32A(&ovi);
278 if (ovi.dwPlatformId == VER_PLATFORM_WIN32_NT)
279 result |= WF_WIN32WOW; /* undocumented WF_WINNT */
284 /***********************************************************************
285 * GetWinDebugInfo (KERNEL.355)
287 BOOL16 WINAPI GetWinDebugInfo(WINDEBUGINFO *lpwdi, UINT16 flags)
289 FIXME(ver, "(%8lx,%d): stub returning 0\n",
290 (unsigned long)lpwdi, flags);
291 /* 0 means not in debugging mode/version */
292 /* Can this type of debugging be used in wine ? */
293 /* Constants: WDI_OPTIONS WDI_FILTER WDI_ALLOCBREAK */
298 /***********************************************************************
299 * SetWinDebugInfo (KERNEL.356)
301 BOOL16 WINAPI SetWinDebugInfo(WINDEBUGINFO *lpwdi)
303 FIXME(ver, "(%8lx): stub returning 0\n", (unsigned long)lpwdi);
304 /* 0 means not in debugging mode/version */
305 /* Can this type of debugging be used in wine ? */
306 /* Constants: WDI_OPTIONS WDI_FILTER WDI_ALLOCBREAK */
311 /***********************************************************************
312 * DebugFillBuffer (KERNEL.329)
315 * Should fill lpBuffer only if DBO_BUFFERFILL has been set by SetWinDebugInfo()
317 void WINAPI DebugFillBuffer(LPSTR lpBuffer, WORD wBytes)
319 memset(lpBuffer, DBGFILL_BUFFER, wBytes);
322 /***********************************************************************
323 * DiagQuery (KERNEL.339)
325 * returns TRUE if Win called with "/b" (bootlog.txt)
327 BOOL16 WINAPI DiagQuery()
329 /* perhaps implement a Wine "/b" command line flag sometime ? */
333 /***********************************************************************
334 * DiagOutput (KERNEL.340)
336 * writes a debug string into <windir>\bootlog.txt
338 void WINAPI DiagOutput(LPCSTR str)
341 DPRINTF("DIAGOUTPUT:%s\n", debugstr_a(str));
344 /***********************************************************************
345 * OaBuildVersion [OLEAUT32.170]
347 UINT32 WINAPI OaBuildVersion()
349 WINDOWS_VERSION ver = VERSION_GetVersion();
351 switch(VersionData[ver].getVersion32)
353 case 0x80000a03: /* Win 3.1 */
354 return 0x140fd1; /* from Win32s 1.1e */
355 case 0xc0000004: /* Win 95 */
357 case 0x04213303: /* NT 3.51 */
358 return 0x0; /* FIXME */
359 case 0x05650004: /* NT 4.0 */
365 /***********************************************************************
366 * VERSION_OsIsUnicode [internal]
369 * some functions getting sometimes LPSTR sometimes LPWSTR...
372 BOOL32 VERSION_OsIsUnicode(void)
374 switch(VERSION_GetVersion())