diff --git a/dlls/kernel/Makefile.in b/dlls/kernel/Makefile.in
index 3ad890951ae7a00f3d5401acd1e533e5b516ddb4..d3cc40cffe2d80757fc17aa118810e98bf1f7ffd 100644
--- a/dlls/kernel/Makefile.in
+++ b/dlls/kernel/Makefile.in
@@ -64,6 +64,7 @@ C_SRCS = \
 	time.c \
 	toolhelp.c \
 	utthunk.c \
+	version.c \
 	vxd.c \
 	win87em.c \
 	windebug.c \
diff --git a/dlls/kernel/process.c b/dlls/kernel/process.c
index 272e791040779353d50a7b5c1f34c2180fcb95b7..09bc9d164e266b6286e26720f76bb49e7bf8ecb5 100644
--- a/dlls/kernel/process.c
+++ b/dlls/kernel/process.c
@@ -2074,10 +2074,20 @@ BOOL WINAPI WriteProcessMemory( HANDLE process, LPVOID addr, LPCVOID buffer, SIZ
     return !status;
 }
 
+
+/****************************************************************************
+ *		FlushInstructionCache (KERNEL32.@)
+ */
+BOOL WINAPI FlushInstructionCache(HANDLE hProcess, LPCVOID lpBaseAddress, SIZE_T dwSize)
+{
+    if (GetVersion() & 0x80000000) return TRUE; /* not NT, always TRUE */
+    FIXME("(%p,%p,0x%08lx): stub\n",hProcess, lpBaseAddress, dwSize);
+    return TRUE;
+}
+
+
 /******************************************************************
  *		GetProcessIoCounters (KERNEL32.@)
- *
- *
  */
 BOOL WINAPI GetProcessIoCounters(HANDLE hProcess, PIO_COUNTERS ioc)
 {
diff --git a/dlls/kernel/version.c b/dlls/kernel/version.c
new file mode 100644
index 0000000000000000000000000000000000000000..053eaeedd25a170cbfc1d072b1ee72760eb28e4b
--- /dev/null
+++ b/dlls/kernel/version.c
@@ -0,0 +1,459 @@
+/*
+ * Windows and DOS version functions
+ *
+ * Copyright 1997 Marcus Meissner
+ * Copyright 1998 Patrik Stridvall
+ * Copyright 1998, 2003 Andreas Mohr
+ * Copyright 1997, 2003 Alexandre Julliard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include "ntstatus.h"
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winreg.h"
+#include "winternl.h"
+#include "winerror.h"
+#include "wine/winbase16.h"
+#include "wine/unicode.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ver);
+
+/**********************************************************************
+ *         parse_dos_version
+ *
+ * Parse the contents of the Version key.
+ */
+static WORD parse_dos_version( HKEY hkey )
+{
+    static const WCHAR DosW[] = {'D','O','S',0};
+
+    UNICODE_STRING valueW;
+    int hi, lo;
+    char tmp[64], buffer[50];
+    KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)tmp;
+    DWORD count, len;
+    WORD ret = 0;
+
+    RtlInitUnicodeString( &valueW, DosW );
+    if (!NtQueryValueKey( hkey, &valueW, KeyValuePartialInformation, tmp, sizeof(tmp), &count ))
+    {
+        RtlUnicodeToMultiByteN( buffer, sizeof(buffer)-1, &len,
+                                (WCHAR *)info->Data, info->DataLength );
+        buffer[len] = 0;
+
+        if (sscanf( buffer, "%d.%d", &hi, &lo ) == 2) ret = MAKEWORD( lo, hi );
+        else MESSAGE("Wrong format for DOS version in config file. Use \"x.xx\"\n");
+    }
+    return ret;
+}
+
+
+/**********************************************************************
+ *         get_dos_version
+ */
+WORD get_dos_version(void)
+{
+    OBJECT_ATTRIBUTES attr;
+    UNICODE_STRING nameW;
+    HKEY hkey, config_key;
+    WCHAR buffer[MAX_PATH];
+    WORD ret = 0;
+
+    static const WCHAR configW[] = {'M','a','c','h','i','n','e','\\',
+                                    'S','o','f','t','w','a','r','e','\\',
+                                    'W','i','n','e','\\',
+                                    'W','i','n','e','\\',
+                                    'C','o','n','f','i','g',0};
+    static const WCHAR appdefaultsW[] = {'A','p','p','D','e','f','a','u','l','t','s','\\',0};
+    static const WCHAR versionW[] = {'\\','V','e','r','s','i','o','n',0};
+
+    attr.Length = sizeof(attr);
+    attr.RootDirectory = 0;
+    attr.ObjectName = &nameW;
+    attr.Attributes = 0;
+    attr.SecurityDescriptor = NULL;
+    attr.SecurityQualityOfService = NULL;
+    RtlInitUnicodeString( &nameW, configW );
+
+    if (NtOpenKey( &config_key, KEY_ALL_ACCESS, &attr )) return 0;
+    attr.RootDirectory = config_key;
+
+    /* open AppDefaults\\appname\\Version key */
+    if (GetModuleFileNameW( 0, buffer, sizeof(buffer)/sizeof(WCHAR) ))
+    {
+        WCHAR *p, *appname, appversion[MAX_PATH+20];
+
+        appname = buffer;
+        if ((p = strrchrW( appname, '/' ))) appname = p + 1;
+        if ((p = strrchrW( appname, '\\' ))) appname = p + 1;
+
+        strcpyW( appversion, appdefaultsW );
+        strcatW( appversion, appname );
+        strcatW( appversion, versionW );
+
+        TRACE( "getting version from %s\n", debugstr_w(appversion) );
+        RtlInitUnicodeString( &nameW, appversion );
+
+        if (!NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ))
+        {
+            ret = parse_dos_version( hkey );
+            NtClose( hkey );
+        }
+    }
+
+    if (!ret)
+    {
+        TRACE( "getting default version\n" );
+        RtlInitUnicodeString( &nameW, versionW + 1 );
+        if (!NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ))
+        {
+            ret = parse_dos_version( hkey );
+            NtClose( hkey );
+        }
+    }
+
+    NtClose( config_key );
+    return ret;
+}
+
+
+/***********************************************************************
+ *         GetVersion   (KERNEL.3)
+ */
+DWORD WINAPI GetVersion16(void)
+{
+    static WORD dosver, winver;
+
+    if (!dosver)  /* not determined yet */
+    {
+        RTL_OSVERSIONINFOEXW info;
+
+        info.dwOSVersionInfoSize = sizeof(info);
+        if (RtlGetVersion( &info ) != STATUS_SUCCESS) return 0;
+
+        if (info.dwMajorVersion <= 3)
+            winver = MAKEWORD( info.dwMajorVersion, info.dwMinorVersion );
+        else
+            winver = MAKEWORD( 3, 95 );
+
+        switch(info.dwPlatformId)
+        {
+        case VER_PLATFORM_WIN32s:
+            if ((dosver = get_dos_version())) break;  /* got the configured version */
+
+            switch(MAKELONG( info.dwMinorVersion, info.dwMajorVersion ))
+            {
+            case 0x0200:
+                dosver = 0x0303;  /* DOS 3.3 for Windows 2.0 */
+                break;
+            case 0x0300:
+                dosver = 0x0500;  /* DOS 5.0 for Windows 3.0 */
+                break;
+            default:
+                dosver = 0x0616;  /* DOS 6.22 for Windows 3.1 and later */
+                break;
+            }
+            break;
+        case VER_PLATFORM_WIN32_WINDOWS:
+            /* DOS 8.0 for WinME, 7.0 for Win95/98 */
+            if (info.dwMinorVersion >= 90) dosver = 0x0800;
+            else dosver = 0x0700;
+            break;
+        case VER_PLATFORM_WIN32_NT:
+            dosver = 0x0500;  /* always DOS 5.0 for NT */
+            break;
+        }
+        TRACE( "DOS %d.%02d Win %d.%02d\n",
+               HIBYTE(dosver), LOBYTE(dosver), LOBYTE(winver), HIBYTE(winver) );
+    }
+    return MAKELONG( winver, dosver );
+}
+
+
+/***********************************************************************
+ *         GetVersion   (KERNEL32.@)
+ */
+DWORD WINAPI GetVersion(void)
+{
+    RTL_OSVERSIONINFOEXW info;
+
+    info.dwOSVersionInfoSize = sizeof(info);
+    if (RtlGetVersion( &info ) != STATUS_SUCCESS) return 0;
+
+    return MAKELONG( MAKEWORD( info.dwMajorVersion, info.dwMinorVersion ),
+                     LOWORD(info.dwBuildNumber) | ((info.dwPlatformId ^ 2) << 14) );
+}
+
+
+/***********************************************************************
+ *         GetVersionEx   (KERNEL.149)
+ */
+BOOL16 WINAPI GetVersionEx16(OSVERSIONINFO16 *v)
+{
+    OSVERSIONINFOA info;
+
+    if (v->dwOSVersionInfoSize < sizeof(OSVERSIONINFO16))
+    {
+        WARN("wrong OSVERSIONINFO size from app\n");
+        return FALSE;
+    }
+
+    info.dwOSVersionInfoSize = sizeof(info);
+    if (!GetVersionExA( &info )) return FALSE;
+
+    v->dwMajorVersion = info.dwMajorVersion;
+    v->dwMinorVersion = info.dwMinorVersion;
+    v->dwBuildNumber  = info.dwBuildNumber;
+    v->dwPlatformId   = info.dwPlatformId;
+    strcpy( v->szCSDVersion, info.szCSDVersion );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *         GetVersionExA   (KERNEL32.@)
+ */
+BOOL WINAPI GetVersionExA(OSVERSIONINFOA *v)
+{
+    RTL_OSVERSIONINFOEXW infoW;
+
+    if (v->dwOSVersionInfoSize != sizeof(OSVERSIONINFOA) &&
+        v->dwOSVersionInfoSize != sizeof(OSVERSIONINFOEXA))
+    {
+        WARN("wrong OSVERSIONINFO size from app (got: %ld, expected: %d or %d)\n",
+                        v->dwOSVersionInfoSize, sizeof(OSVERSIONINFOA),
+                        sizeof(OSVERSIONINFOEXA));
+        return FALSE;
+    }
+
+    infoW.dwOSVersionInfoSize = sizeof(infoW);
+    if (RtlGetVersion( &infoW ) != STATUS_SUCCESS) return FALSE;
+
+    v->dwMajorVersion = infoW.dwMajorVersion;
+    v->dwMinorVersion = infoW.dwMinorVersion;
+    v->dwBuildNumber  = infoW.dwBuildNumber;
+    v->dwPlatformId   = infoW.dwPlatformId;
+    WideCharToMultiByte( CP_ACP, 0, infoW.szCSDVersion, -1,
+                         v->szCSDVersion, sizeof(v->szCSDVersion), NULL, NULL );
+
+    if(v->dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXA))
+    {
+        LPOSVERSIONINFOEXA vex = (LPOSVERSIONINFOEXA) v;
+        vex->wServicePackMajor = infoW.wServicePackMajor;
+        vex->wServicePackMinor = infoW.wServicePackMinor;
+        vex->wSuiteMask        = infoW.wSuiteMask;
+        vex->wProductType      = infoW.wProductType;
+    }
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *         GetVersionExW   (KERNEL32.@)
+ */
+BOOL WINAPI GetVersionExW( OSVERSIONINFOW *info )
+{
+    if (info->dwOSVersionInfoSize != sizeof(OSVERSIONINFOW) &&
+        info->dwOSVersionInfoSize != sizeof(OSVERSIONINFOEXW))
+    {
+        WARN("wrong OSVERSIONINFO size from app (got: %ld, expected: %d or %d)\n",
+                        info->dwOSVersionInfoSize, sizeof(OSVERSIONINFOW),
+                        sizeof(OSVERSIONINFOEXW));
+        return FALSE;
+    }
+    return (RtlGetVersion( (RTL_OSVERSIONINFOEXW *)info ) == STATUS_SUCCESS);
+}
+
+
+/******************************************************************************
+ *        VerifyVersionInfoA   (KERNEL32.@)
+ */
+BOOL WINAPI VerifyVersionInfoA( LPOSVERSIONINFOEXA lpVersionInfo, DWORD dwTypeMask,
+                                DWORDLONG dwlConditionMask)
+{
+    OSVERSIONINFOEXW verW;
+
+    verW.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
+    verW.dwMajorVersion = lpVersionInfo->dwMajorVersion;
+    verW.dwMinorVersion = lpVersionInfo->dwMinorVersion;
+    verW.dwBuildNumber = lpVersionInfo->dwBuildNumber;
+    verW.dwPlatformId = lpVersionInfo->dwPlatformId;
+    verW.wServicePackMajor = lpVersionInfo->wServicePackMajor;
+    verW.wServicePackMinor = lpVersionInfo->wServicePackMinor;
+    verW.wSuiteMask = lpVersionInfo->wSuiteMask;
+    verW.wProductType = lpVersionInfo->wProductType;
+    verW.wReserved = lpVersionInfo->wReserved;
+
+    return VerifyVersionInfoW(&verW, dwTypeMask, dwlConditionMask);
+}
+
+
+/******************************************************************************
+ *        VerifyVersionInfoW   (KERNEL32.@)
+ */
+BOOL WINAPI VerifyVersionInfoW( LPOSVERSIONINFOEXW lpVersionInfo, DWORD dwTypeMask,
+                                DWORDLONG dwlConditionMask)
+{
+    switch(RtlVerifyVersionInfo( lpVersionInfo, dwTypeMask, dwlConditionMask ))
+    {
+    case STATUS_INVALID_PARAMETER:
+        SetLastError( ERROR_BAD_ARGUMENTS );
+        return FALSE;
+    case STATUS_REVISION_MISMATCH:
+        SetLastError( ERROR_OLD_WIN_VERSION );
+        return FALSE;
+    }
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *          GetWinFlags   (KERNEL.132)
+ */
+DWORD WINAPI GetWinFlags16(void)
+{
+  static const long cpuflags[5] =
+    { WF_CPU086, WF_CPU186, WF_CPU286, WF_CPU386, WF_CPU486 };
+  SYSTEM_INFO si;
+  OSVERSIONINFOA ovi;
+  DWORD result;
+
+  GetSystemInfo(&si);
+
+  /* There doesn't seem to be any Pentium flag.  */
+  result = cpuflags[min(si.wProcessorLevel, 4)] | WF_ENHANCED | WF_PMODE | WF_80x87 | WF_PAGING;
+  if (si.wProcessorLevel >= 4) result |= WF_HASCPUID;
+  ovi.dwOSVersionInfoSize = sizeof(ovi);
+  GetVersionExA(&ovi);
+  if (ovi.dwPlatformId == VER_PLATFORM_WIN32_NT)
+      result |= WF_WIN32WOW; /* undocumented WF_WINNT */
+  return result;
+}
+
+
+#if 0
+/* Not used at this time. This is here for documentation only */
+
+/* WINDEBUGINFO flags values */
+#define WDI_OPTIONS         0x0001
+#define WDI_FILTER          0x0002
+#define WDI_ALLOCBREAK      0x0004
+
+/* dwOptions values */
+#define DBO_CHECKHEAP       0x0001
+#define DBO_BUFFERFILL      0x0004
+#define DBO_DISABLEGPTRAPPING 0x0010
+#define DBO_CHECKFREE       0x0020
+
+#define DBO_SILENT          0x8000
+
+#define DBO_TRACEBREAK      0x2000
+#define DBO_WARNINGBREAK    0x1000
+#define DBO_NOERRORBREAK    0x0800
+#define DBO_NOFATALBREAK    0x0400
+#define DBO_INT3BREAK       0x0100
+
+/* DebugOutput flags values */
+#define DBF_TRACE           0x0000
+#define DBF_WARNING         0x4000
+#define DBF_ERROR           0x8000
+#define DBF_FATAL           0xc000
+
+/* dwFilter values */
+#define DBF_KERNEL          0x1000
+#define DBF_KRN_MEMMAN      0x0001
+#define DBF_KRN_LOADMODULE  0x0002
+#define DBF_KRN_SEGMENTLOAD 0x0004
+#define DBF_USER            0x0800
+#define DBF_GDI             0x0400
+#define DBF_MMSYSTEM        0x0040
+#define DBF_PENWIN          0x0020
+#define DBF_APPLICATION     0x0008
+#define DBF_DRIVER          0x0010
+
+#endif /* NOLOGERROR */
+
+
+/***********************************************************************
+ *          GetWinDebugInfo   (KERNEL.355)
+ */
+BOOL16 WINAPI GetWinDebugInfo16(WINDEBUGINFO16 *lpwdi, UINT16 flags)
+{
+    FIXME("(%8lx,%d): stub returning 0\n",
+          (unsigned long)lpwdi, flags);
+    /* 0 means not in debugging mode/version */
+    /* Can this type of debugging be used in wine ? */
+    /* Constants: WDI_OPTIONS WDI_FILTER WDI_ALLOCBREAK */
+    return 0;
+}
+
+
+/***********************************************************************
+ *          SetWinDebugInfo   (KERNEL.356)
+ */
+BOOL16 WINAPI SetWinDebugInfo16(WINDEBUGINFO16 *lpwdi)
+{
+    FIXME("(%8lx): stub returning 0\n", (unsigned long)lpwdi);
+    /* 0 means not in debugging mode/version */
+    /* Can this type of debugging be used in wine ? */
+    /* Constants: WDI_OPTIONS WDI_FILTER WDI_ALLOCBREAK */
+    return 0;
+}
+
+
+/***********************************************************************
+ *           K329                    (KERNEL.329)
+ *
+ * TODO:
+ * Should fill lpBuffer only if DBO_BUFFERFILL has been set by SetWinDebugInfo()
+ */
+void WINAPI DebugFillBuffer(LPSTR lpBuffer, WORD wBytes)
+{
+        memset(lpBuffer, DBGFILL_BUFFER, wBytes);
+}
+
+/***********************************************************************
+ *           DiagQuery                          (KERNEL.339)
+ *
+ * returns TRUE if Win called with "/b" (bootlog.txt)
+ */
+BOOL16 WINAPI DiagQuery16(void)
+{
+        /* perhaps implement a Wine "/b" command line flag sometime ? */
+        return FALSE;
+}
+
+/***********************************************************************
+ *           DiagOutput                         (KERNEL.340)
+ *
+ * writes a debug string into <windir>\bootlog.txt
+ */
+void WINAPI DiagOutput16(LPCSTR str)
+{
+        /* FIXME */
+        DPRINTF("DIAGOUTPUT:%s\n", debugstr_a(str));
+}
diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in
index 25f4277bf38651a5f9bccc4d7e6df10ee7c933d0..607ee97ae7689b78daeca0c13d65846574c8f454 100644
--- a/dlls/ntdll/Makefile.in
+++ b/dlls/ntdll/Makefile.in
@@ -25,7 +25,6 @@ C_SRCS = \
 	$(TOPOBJDIR)/misc/cpu.c \
 	$(TOPOBJDIR)/misc/options.c \
 	$(TOPOBJDIR)/misc/registry.c \
-	$(TOPOBJDIR)/misc/version.c \
 	$(TOPOBJDIR)/msdos/dpmi.c \
 	$(TOPOBJDIR)/scheduler/handle.c \
 	$(TOPOBJDIR)/scheduler/process.c \
@@ -62,6 +61,7 @@ C_SRCS = \
 	string.c \
 	sync.c \
 	sysdeps.c \
+	version.c \
 	thread.c \
 	time.c \
 	virtual.c \
diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c
index 545616fa67810bd4bf9bde650717656b35c1bfe0..bc8cd7a55e2d87cb6a1567cba7c05f454413be0b 100644
--- a/dlls/ntdll/rtl.c
+++ b/dlls/ntdll/rtl.c
@@ -500,49 +500,6 @@ void WINAPI RtlAssert(LPVOID x1,LPVOID x2,DWORD x3, DWORD x4)
 	FIXME("(%p,%p,0x%08lx,0x%08lx),stub\n",x1,x2,x3,x4);
 }
 
-/******************************************************************************
- *  RtlGetNtVersionNumbers       [NTDLL.@]
- *
- * Get the version numbers of the run time library.
- *
- * PARAMS
- *  major [O] Destination for the Major version
- *  minor [O] Destination for the Minor version
- *  build [O] Destination for the Build version
- *
- * RETURNS
- *  Nothing.
- *
- * NOTES
- * Introduced in Windows XP (NT5.1)
- */
-void WINAPI RtlGetNtVersionNumbers(LPDWORD major, LPDWORD minor, LPDWORD build)
-{
-	OSVERSIONINFOEXW versionInfo;
-	versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
-	GetVersionExW((OSVERSIONINFOW*)&versionInfo);
-
-	if (major)
-	{
-		/* msvcrt.dll as released with XP Home fails in DLLMain() if the
-		 * major version is not 5. So, we should never set a version < 5 ...
-		 * This makes sense since this call didn't exist before XP anyway.
-		 */
-		*major = versionInfo.dwMajorVersion < 5 ? 5 : versionInfo.dwMajorVersion;
-	}
-
-	if (minor)
-	{
-		*minor = versionInfo.dwMinorVersion;
-	}
-
-	if (build)
-	{
-		/* FIXME: Does anybody know the real formula? */
-		*build = (0xF0000000 | versionInfo.dwBuildNumber);
-	}
-}
-
 /*************************************************************************
  * RtlFillMemoryUlong   [NTDLL.@]
  *
diff --git a/dlls/ntdll/version.c b/dlls/ntdll/version.c
new file mode 100644
index 0000000000000000000000000000000000000000..880ae3184137469e901fd3c2f32ec14b81ac193a
--- /dev/null
+++ b/dlls/ntdll/version.c
@@ -0,0 +1,733 @@
+/*
+ * Windows and DOS version functions
+ *
+ * Copyright 1997 Marcus Meissner
+ * Copyright 1998 Patrik Stridvall
+ * Copyright 1998, 2003 Andreas Mohr
+ * Copyright 1997, 2003 Alexandre Julliard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include "ntstatus.h"
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winreg.h"
+#include "winternl.h"
+#include "winerror.h"
+#include "module.h"
+#include "wine/unicode.h"
+#include "wine/debug.h"
+#include "ntdll_misc.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ver);
+
+typedef enum
+{
+    WIN20,   /* Windows 2.0 */
+    WIN30,   /* Windows 3.0 */
+    WIN31,   /* Windows 3.1 */
+    WIN95,   /* Windows 95 */
+    WIN98,   /* Windows 98 */
+    WINME,   /* Windows Me */
+    NT351,   /* Windows NT 3.51 */
+    NT40,    /* Windows NT 4.0 */
+    NT2K,    /* Windows 2000 */
+    WINXP,   /* Windows XP */
+    WIN2K3,  /* Windows 2003 */
+    NB_WINDOWS_VERSIONS
+} WINDOWS_VERSION;
+
+/* FIXME: compare values below with original and fix.
+ * An *excellent* win9x version page (ALL versions !)
+ * can be found at members.aol.com/axcel216/ver.htm */
+static const RTL_OSVERSIONINFOEXW VersionData[NB_WINDOWS_VERSIONS] =
+{
+    /* WIN20 FIXME: verify values */
+    {
+        sizeof(RTL_OSVERSIONINFOEXW), 2, 0, 0, VER_PLATFORM_WIN32s,
+        {'W','i','n','3','2','s',' ','1','.','3',0},
+        0, 0, 0, 0, 0
+    },
+    /* WIN30 FIXME: verify values */
+    {
+        sizeof(RTL_OSVERSIONINFOEXW), 3, 0, 0, VER_PLATFORM_WIN32s,
+        {'W','i','n','3','2','s',' ','1','.','3',0},
+        0, 0, 0, 0, 0
+    },
+    /* WIN31 */
+    {
+        sizeof(RTL_OSVERSIONINFOEXW), 3, 10, 0, VER_PLATFORM_WIN32s,
+        {'W','i','n','3','2','s',' ','1','.','3',0},
+        0, 0, 0, 0, 0
+    },
+    /* WIN95 */
+    {
+        /* Win95:       4, 0, 0x40003B6, ""
+         * Win95sp1:    4, 0, 0x40003B6, " A " (according to doc)
+         * Win95osr2:   4, 0, 0x4000457, " B " (according to doc)
+         * Win95osr2.1: 4, 3, 0x40304BC, " B " (according to doc)
+         * Win95osr2.5: 4, 3, 0x40304BE, " C " (according to doc)
+         * Win95a/b can be discerned via regkey SubVersionNumber
+         * See also:
+         * http://support.microsoft.com/support/kb/articles/q158/2/38.asp
+         */
+        sizeof(RTL_OSVERSIONINFOEXW), 4, 0, 0x40003B6, VER_PLATFORM_WIN32_WINDOWS,
+        {0},
+        0, 0, 0, 0, 0
+    },
+    /* WIN98 (second edition) */
+    {
+        /* Win98:   4, 10, 0x40A07CE, " "   4.10.1998
+         * Win98SE: 4, 10, 0x40A08AE, " A " 4.10.2222
+         */
+        sizeof(RTL_OSVERSIONINFOEXW), 4, 10, 0x40A08AE, VER_PLATFORM_WIN32_WINDOWS,
+        {' ','A',' ',0},
+        0, 0, 0, 0, 0
+    },
+    /* WINME */
+    {
+        sizeof(RTL_OSVERSIONINFOEXW), 4, 90, 0x45A0BB8, VER_PLATFORM_WIN32_WINDOWS,
+        {' ',0},
+        0, 0, 0, 0, 0
+    },
+    /* NT351 */
+    {
+        sizeof(RTL_OSVERSIONINFOEXW), 3, 51, 0x421, VER_PLATFORM_WIN32_NT,
+        {'S','e','r','v','i','c','e',' ','P','a','c','k',' ','2',0},
+        0, 0, 0, 0, 0
+    },
+    /* NT40 */
+    {
+        sizeof(RTL_OSVERSIONINFOEXW), 4, 0, 0x565, VER_PLATFORM_WIN32_NT,
+        {'S','e','r','v','i','c','e',' ','P','a','c','k',' ','6',0},
+        6, 0, 0, VER_NT_WORKSTATION, 0
+    },
+    /* NT2K */
+    {
+        sizeof(RTL_OSVERSIONINFOEXW), 5, 0, 0x893, VER_PLATFORM_WIN32_NT,
+        {'S','e','r','v','i','c','e',' ','P','a','c','k',' ','3',0},
+        3, 0, 0, VER_NT_WORKSTATION, 30 /* FIXME: Great, a reserved field with a value! */
+    },
+    /* WINXP */
+    {
+        sizeof(RTL_OSVERSIONINFOEXW), 5, 1, 0xA28, VER_PLATFORM_WIN32_NT,
+        {'S','e','r','v','i','c','e',' ','P','a','c','k',' ','1',0},
+        1, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 30 /* FIXME: Great, a reserved field with a value! */
+    },
+    /* WIN2K3 */
+    {
+        sizeof(RTL_OSVERSIONINFOEXW), 5, 2, 0xECE, VER_PLATFORM_WIN32_NT,
+        {0},
+        0, 0, VER_SUITE_SINGLEUSERTS, VER_NT_SERVER, 0
+    }
+};
+
+static const char * const WinVersionNames[NB_WINDOWS_VERSIONS] =
+{ /* no spaces in here ! */
+    "win20",                      /* WIN20 */
+    "win30",                      /* WIN30 */
+    "win31",                      /* WIN31 */
+    "win95",                      /* WIN95 */
+    "win98",                      /* WIN98 */
+    "winme",                      /* WINME */
+    "nt351",                      /* NT351 */
+    "nt40",                       /* NT40 */
+    "win2000,win2k,nt2k,nt2000",  /* NT2K */
+    "winxp",                      /* WINXP */
+    "win2003,win2k3"              /* WIN2K3 */
+};
+
+/* names to print out in debug traces */
+static const char * const debug_names[NB_WINDOWS_VERSIONS] =
+{
+    "Windows 2.0",       /* WIN20 */
+    "Windows 3.0",       /* WIN30 */
+    "Windows 3.1",       /* WIN31 */
+    "Windows 95",        /* WIN95 */
+    "Windows 98",        /* WIN98 */
+    "Windows Me",        /* WINME */
+    "Windows NT 3.51",   /* NT351 */
+    "Windows NT 4.0",    /* NT40 */
+    "Windows 2000",      /* NT2K */
+    "Windows XP",        /* WINXP */
+    "Windows 2003"       /* WIN2K3 */
+};
+
+/* if one of the following dlls is importing ntdll the windows
+version autodetection switches wine to unicode (nt 3.51 or 4.0) */
+static const WCHAR special_dlls[][16] =
+{
+    {'c','o','m','d','l','g','3','2','.','d','l','l',0},
+    {'c','o','m','c','t','l','3','2','.','d','l','l',0},
+    {'s','h','e','l','l','3','2','.','d','l','l',0},
+    {'o','l','e','3','2','.','d','l','l',0},
+    {'r','p','c','r','t','4','.','d','l','l',0}
+};
+
+/* the current version has not been autodetected but forced via cmdline */
+static BOOL versionForced = FALSE;
+static WINDOWS_VERSION forcedWinVersion; /* init value irrelevant */
+
+/**********************************************************************
+ *         parse_win_version
+ *
+ * Parse the contents of the Version key.
+ */
+static BOOL parse_win_version( HKEY hkey )
+{
+    static const WCHAR WindowsW[] = {'W','i','n','d','o','w','s',0};
+
+    UNICODE_STRING valueW;
+    char tmp[64], buffer[50];
+    KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)tmp;
+    DWORD count, len;
+    int i;
+
+    RtlInitUnicodeString( &valueW, WindowsW );
+    if (NtQueryValueKey( hkey, &valueW, KeyValuePartialInformation, tmp, sizeof(tmp), &count ))
+        return FALSE;
+
+    RtlUnicodeToMultiByteN( buffer, sizeof(buffer)-1, &len, (WCHAR *)info->Data, info->DataLength );
+    buffer[len] = 0;
+
+    for (i = 0; i < NB_WINDOWS_VERSIONS; i++)
+    {
+        const char *p, *pCurr = WinVersionNames[i];
+        /* iterate through all winver aliases separated by comma */
+        do {
+            p = strchr(pCurr, ',');
+            len = p ? p - pCurr : strlen(pCurr);
+            if ( (!strncmp( pCurr, buffer, len )) && (buffer[len] == 0) )
+            {
+                forcedWinVersion = i;
+                versionForced = TRUE;
+                TRACE( "got win version %s\n", WinVersionNames[forcedWinVersion] );
+                return TRUE;
+            }
+            pCurr = p+1;
+        } while (p);
+    }
+
+    MESSAGE("Invalid Windows version value '%s' specified in config file.\n", buffer );
+    MESSAGE("Valid versions are:" );
+    for (i = 0; i < NB_WINDOWS_VERSIONS; i++)
+    {
+        /* only list the first, "official" alias in case of aliases */
+        const char *pCurr = WinVersionNames[i];
+        const char *p = strchr(pCurr, ',');
+        len = (p) ? p - pCurr : strlen(pCurr);
+
+        MESSAGE(" '%.*s'%c", (int)len, pCurr, (i == NB_WINDOWS_VERSIONS - 1) ? '\n' : ',' );
+    }
+    return FALSE;
+}
+
+
+/**********************************************************************
+ *         VERSION_Init
+ */
+void VERSION_Init( const char *appname )
+{
+    OBJECT_ATTRIBUTES attr;
+    UNICODE_STRING nameW;
+    HKEY hkey, config_key;
+    static const WCHAR configW[] = {'M','a','c','h','i','n','e','\\',
+                                    'S','o','f','t','w','a','r','e','\\',
+                                    'W','i','n','e','\\',
+                                    'W','i','n','e','\\',
+                                    'C','o','n','f','i','g',0};
+    static const WCHAR appdefaultsW[] = {'A','p','p','D','e','f','a','u','l','t','s','\\',0};
+    static const WCHAR versionW[] = {'\\','V','e','r','s','i','o','n',0};
+
+    attr.Length = sizeof(attr);
+    attr.RootDirectory = 0;
+    attr.ObjectName = &nameW;
+    attr.Attributes = 0;
+    attr.SecurityDescriptor = NULL;
+    attr.SecurityQualityOfService = NULL;
+    RtlInitUnicodeString( &nameW, configW );
+
+    if (NtOpenKey( &config_key, KEY_ALL_ACCESS, &attr )) return;
+    attr.RootDirectory = config_key;
+
+    /* open AppDefaults\\appname\\Version key */
+    if (appname && *appname)
+    {
+        const char *p;
+        DWORD len;
+        WCHAR appversion[MAX_PATH+20];
+        BOOL got_win_ver = FALSE;
+
+        if ((p = strrchr( appname, '/' ))) appname = p + 1;
+        if ((p = strrchr( appname, '\\' ))) appname = p + 1;
+
+        strcpyW( appversion, appdefaultsW );
+        len = strlenW(appversion);
+        RtlMultiByteToUnicodeN( appversion + len, sizeof(appversion) - len*sizeof(WCHAR),
+                                &len, appname, strlen(appname)+1 );
+        strcatW( appversion, versionW );
+        TRACE( "getting version from %s\n", debugstr_w(appversion) );
+        RtlInitUnicodeString( &nameW, appversion );
+
+        if (!NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ))
+        {
+            got_win_ver = parse_win_version( hkey );
+            NtClose( hkey );
+        }
+        if (got_win_ver) goto done;
+    }
+
+    TRACE( "getting default version\n" );
+    RtlInitUnicodeString( &nameW, versionW + 1 );
+    if (!NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ))
+    {
+        parse_win_version( hkey );
+        NtClose( hkey );
+    }
+
+ done:
+    NtClose( config_key );
+}
+
+
+/**********************************************************************
+ *      VERSION_GetSystemDLLVersion
+ *
+ * This function tries to figure out if a given (native) dll comes from
+ * win95/98 or winnt. Since all values in the OptionalHeader are not a
+ * usable hint, we test if a dll imports the ntdll.
+ * This is at least working for all system dlls like comctl32, comdlg32 and
+ * shell32.
+ * If you have a better idea to figure this out...
+ */
+static DWORD VERSION_GetSystemDLLVersion( HMODULE hmod )
+{
+    DWORD size;
+    IMAGE_IMPORT_DESCRIPTOR *pe_imp;
+
+    if ((pe_imp = RtlImageDirectoryEntryToData( hmod, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size )))
+    {
+        for ( ; pe_imp->Name; pe_imp++)
+        {
+            char * name = (char *)hmod + (unsigned int)pe_imp->Name;
+            TRACE("%s\n", name);
+
+            if (!strncasecmp(name, "ntdll", 5))
+            {
+              switch(RtlImageNtHeader(hmod)->OptionalHeader.MajorOperatingSystemVersion) {
+                  case 3:
+                          MESSAGE("WARNING: very old native DLL (NT 3.x) used, might cause instability.\n");
+                          return NT351;
+                  case 4: return NT40;
+                  case 5: return NT2K;
+                  case 6: return WINXP;
+                  case 7: return WIN2K3; /* FIXME: Not sure, should be verified with a Win2K3 dll */
+                  default:
+                          FIXME("Unknown DLL OS version, please report !!\n");
+                          return WIN2K3;
+              }
+            }
+        }
+    }
+    return WIN95;
+}
+
+
+/**********************************************************************
+ *      VERSION_GetLinkedDllVersion
+ *
+ * Some version data (not reliable!):
+ * linker/OS/image/subsys
+ *
+ * x.xx/1.00/0.00/3.10  Win32s          (any version ?)
+ * 2.39/1.00/0.00/3.10  Win32s          freecell.exe (any version)
+ * 2.50/1.00/4.00/4.00  Win32s 1.30     winhlp32.exe
+ * 2.60/3.51/3.51/3.51  NT351SP5        system dlls
+ * 2.60/3.51/3.51/4.00  NT351SP5        comctl32 dll
+ * 2.xx/1.00/0.00/4.00  Win95           system files
+ * x.xx/4.00/0.00/4.00  Win95           most applications
+ * 3.10/4.00/0.00/4.00  Win98           notepad
+ * x.xx/5.00/5.00/4.00  Win98           system dlls (e.g. comctl32.dll)
+ * x.xx/4.00/4.00/4.00  NT 4            most apps
+ * 5.12/5.00/5.00/4.00  NT4+IE5         comctl32.dll
+ * 5.12/5.00/5.00/4.00  Win98           calc
+ * x.xx/5.00/5.00/4.00  win95/win98/NT4 IE5 files
+ */
+static DWORD VERSION_GetLinkedDllVersion(void)
+{
+    WINDOWS_VERSION WinVersion = NB_WINDOWS_VERSIONS;
+    PIMAGE_OPTIONAL_HEADER ophd;
+    IMAGE_NT_HEADERS *nt;
+    const WCHAR *name;
+    PLIST_ENTRY mark, entry;
+    PLDR_MODULE mod;
+    int i;
+
+    /* First check the native dlls provided. These have to be
+       from one windows version */
+
+    mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
+    for (entry = mark->Flink; entry != mark; entry = entry->Flink)
+    {
+        mod = CONTAINING_RECORD(entry, LDR_MODULE, InLoadOrderModuleList);
+        if (mod->Flags & LDR_WINE_INTERNAL) continue;
+        nt = RtlImageNtHeader(mod->BaseAddress);
+        ophd = &nt->OptionalHeader;
+        name = strrchrW( mod->FullDllName.Buffer, '\\' );
+        if (name) name++;
+        else name = mod->FullDllName.Buffer;
+
+        TRACE("%s: %02x.%02x/%02x.%02x/%02x.%02x/%02x.%02x\n",
+              debugstr_w(name), ophd->MajorLinkerVersion, ophd->MinorLinkerVersion,
+              ophd->MajorOperatingSystemVersion, ophd->MinorOperatingSystemVersion,
+              ophd->MajorImageVersion, ophd->MinorImageVersion,
+              ophd->MajorSubsystemVersion, ophd->MinorSubsystemVersion);
+
+        for (i = 0; i < sizeof(special_dlls)/sizeof(special_dlls[0]); i++)
+        {
+            /* test if it is a special dll */
+            if (!strcmpiW(name, special_dlls[i]))
+            {
+                DWORD DllVersion = VERSION_GetSystemDLLVersion(mod->BaseAddress);
+                if (WinVersion == NB_WINDOWS_VERSIONS) WinVersion = DllVersion;
+                else if (WinVersion != DllVersion)
+                {
+                    ERR("You mixed system DLLs from different windows versions! Expect a crash! (%s: expected version %s, but is %s)\n",
+                        debugstr_w(name),
+                        debugstr_w(VersionData[WinVersion].szCSDVersion),
+                        debugstr_w(VersionData[DllVersion].szCSDVersion));
+                    return WIN20; /* this may let the exe exit */
+                }
+                break;
+            }
+        }
+    }
+
+    if(WinVersion != NB_WINDOWS_VERSIONS) return WinVersion;
+
+    /* we are using no external system dlls, look at the exe */
+    nt = RtlImageNtHeader(NtCurrentTeb()->Peb->ImageBaseAddress);
+    ophd = &nt->OptionalHeader;
+
+    TRACE("%02x.%02x/%02x.%02x/%02x.%02x/%02x.%02x\n",
+          ophd->MajorLinkerVersion, ophd->MinorLinkerVersion,
+          ophd->MajorOperatingSystemVersion, ophd->MinorOperatingSystemVersion,
+          ophd->MajorImageVersion, ophd->MinorImageVersion,
+          ophd->MajorSubsystemVersion, ophd->MinorSubsystemVersion);
+
+    /* special nt 3.51 */
+    if (3 == ophd->MajorOperatingSystemVersion && 51 == ophd->MinorOperatingSystemVersion)
+    {
+        return NT351;
+    }
+
+    /* the MajorSubsystemVersion is the only usable sign */
+    if (ophd->MajorSubsystemVersion < 4)
+    {
+        if ( ophd->MajorOperatingSystemVersion == 1
+             && ophd->MinorOperatingSystemVersion == 0)
+        {
+            return WIN31; /* win32s */
+        }
+
+        if (ophd->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
+            return NT351; /* FIXME: NT 3.1, not tested */
+        else
+            return WIN95;
+    }
+
+    return WIN95;
+}
+
+/**********************************************************************
+ *         VERSION_GetVersion
+ *
+ * WARNING !!!
+ * Don't call this function too early during the Wine init,
+ * as pdb->exe_modref (required by VERSION_GetImageVersion()) might still
+ * be NULL in such cases, which causes the winver to ALWAYS be detected
+ * as WIN31.
+ * And as we cache the winver once it has been determined, this is bad.
+ * This can happen much easier than you might think, as this function
+ * is called by EVERY GetVersion*() API !
+ *
+ */
+static const RTL_OSVERSIONINFOEXW *VERSION_GetVersion(void)
+{
+    static WORD winver = 0xffff;
+
+    if (versionForced)
+        return &VersionData[forcedWinVersion];  /* user has overridden any sensible checks */
+
+    if (winver == 0xffff) /* to be determined */
+    {
+        WINDOWS_VERSION retver = VERSION_GetLinkedDllVersion();
+
+        /* cache determined value, but do not store in case of WIN31 */
+        if (retver != WIN31) winver = retver;
+        return &VersionData[retver];
+    }
+    return &VersionData[winver];
+}
+
+
+/***********************************************************************
+ *         RtlGetVersion   (NTDLL.@)
+ */
+NTSTATUS WINAPI RtlGetVersion( RTL_OSVERSIONINFOEXW *info )
+{
+    const RTL_OSVERSIONINFOEXW * const current = VERSION_GetVersion();
+
+    info->dwMajorVersion = current->dwMajorVersion;
+    info->dwMinorVersion = current->dwMinorVersion;
+    info->dwBuildNumber  = current->dwBuildNumber;
+    info->dwPlatformId   = current->dwPlatformId;
+    strcpyW( info->szCSDVersion, current->szCSDVersion );
+    if(info->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOEXW))
+    {
+        info->wServicePackMajor = current->wServicePackMajor;
+        info->wServicePackMinor = current->wServicePackMinor;
+        info->wSuiteMask        = current->wSuiteMask;
+        info->wProductType      = current->wProductType;
+    }
+    TRACE("<-- %s (%s)\n", debug_names[current - VersionData], debugstr_w(current->szCSDVersion) );
+    return STATUS_SUCCESS;
+}
+
+
+/******************************************************************************
+ *  RtlGetNtVersionNumbers   (NTDLL.@)
+ *
+ * Get the version numbers of the run time library.
+ *
+ * PARAMS
+ *  major [O] Destination for the Major version
+ *  minor [O] Destination for the Minor version
+ *  build [O] Destination for the Build version
+ *
+ * RETURNS
+ *  Nothing.
+ *
+ * NOTES
+ * Introduced in Windows XP (NT5.1)
+ */
+void WINAPI RtlGetNtVersionNumbers( LPDWORD major, LPDWORD minor, LPDWORD build )
+{
+    const RTL_OSVERSIONINFOEXW * const current = VERSION_GetVersion();
+
+    if (major) *major = current->dwMajorVersion;
+    if (minor) *minor = current->dwMinorVersion;
+    /* FIXME: Does anybody know the real formula? */
+    if (build) *build = (0xF0000000 | current->dwBuildNumber);
+}
+
+
+/******************************************************************************
+ *        VerifyVersionInfoW   (KERNEL32.@)
+ */
+NTSTATUS WINAPI RtlVerifyVersionInfo( const RTL_OSVERSIONINFOEXW *info,
+                                      DWORD dwTypeMask, DWORDLONG dwlConditionMask )
+{
+    RTL_OSVERSIONINFOEXW ver;
+    NTSTATUS status;
+
+    FIXME("(%p,%lu,%llx): Not all cases correctly implemented yet\n",
+          info, dwTypeMask, dwlConditionMask);
+
+    /* FIXME:
+        - Check the following special case on Windows (various versions):
+          o lp->wSuiteMask == 0 and ver.wSuiteMask != 0 and VER_AND/VER_OR
+          o lp->dwOSVersionInfoSize != sizeof(OSVERSIONINFOEXW)
+        - MSDN talks about some tests being impossible. Check what really happens.
+     */
+
+    ver.dwOSVersionInfoSize = sizeof(ver);
+    if ((status = RtlGetVersion( &ver )) != STATUS_SUCCESS) return status;
+
+    if(!(dwTypeMask && dwlConditionMask)) return STATUS_INVALID_PARAMETER;
+
+    if(dwTypeMask & VER_PRODUCT_TYPE)
+        switch(dwlConditionMask >> 7*3 & 0x07) {
+            case VER_EQUAL:
+                if(ver.wProductType != info->wProductType) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER:
+                if(ver.wProductType <= info->wProductType) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER_EQUAL:
+                if(ver.wProductType < info->wProductType) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS:
+                if(ver.wProductType >= info->wProductType) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS_EQUAL:
+                if(ver.wProductType > info->wProductType) return STATUS_REVISION_MISMATCH;
+                break;
+            default:
+                return STATUS_INVALID_PARAMETER;
+        }
+    if(dwTypeMask & VER_SUITENAME)
+        switch(dwlConditionMask >> 6*3 & 0x07)
+        {
+            case VER_AND:
+                if((info->wSuiteMask & ver.wSuiteMask) != info->wSuiteMask)
+                    return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_OR:
+                if(!(info->wSuiteMask & ver.wSuiteMask) && info->wSuiteMask)
+                    return STATUS_REVISION_MISMATCH;
+                break;
+            default:
+                return STATUS_INVALID_PARAMETER;
+        }
+    if(dwTypeMask & VER_PLATFORMID)
+        switch(dwlConditionMask >> 3*3 & 0x07)
+        {
+            case VER_EQUAL:
+                if(ver.dwPlatformId != info->dwPlatformId) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER:
+                if(ver.dwPlatformId <= info->dwPlatformId) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER_EQUAL:
+                if(ver.dwPlatformId < info->dwPlatformId) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS:
+                if(ver.dwPlatformId >= info->dwPlatformId) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS_EQUAL:
+                if(ver.dwPlatformId > info->dwPlatformId) return STATUS_REVISION_MISMATCH;
+                break;
+            default:
+                return STATUS_INVALID_PARAMETER;
+        }
+    if(dwTypeMask & VER_BUILDNUMBER)
+        switch(dwlConditionMask >> 2*3 & 0x07)
+        {
+            case VER_EQUAL:
+                if(ver.dwBuildNumber != info->dwBuildNumber) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER:
+                if(ver.dwBuildNumber <= info->dwBuildNumber) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER_EQUAL:
+                if(ver.dwBuildNumber < info->dwBuildNumber) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS:
+                if(ver.dwBuildNumber >= info->dwBuildNumber) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS_EQUAL:
+                if(ver.dwBuildNumber > info->dwBuildNumber) return STATUS_REVISION_MISMATCH;
+                break;
+            default:
+                return STATUS_INVALID_PARAMETER;
+        }
+    if(dwTypeMask & VER_MAJORVERSION)
+        switch(dwlConditionMask >> 1*3 & 0x07)
+        {
+            case VER_EQUAL:
+                if(ver.dwMajorVersion != info->dwMajorVersion) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER:
+                if(ver.dwMajorVersion <= info->dwMajorVersion) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER_EQUAL:
+                if(ver.dwMajorVersion < info->dwMajorVersion) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS:
+                if(ver.dwMajorVersion >= info->dwMajorVersion) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS_EQUAL:
+                if(ver.dwMajorVersion > info->dwMajorVersion) return STATUS_REVISION_MISMATCH;
+                break;
+            default:
+                return STATUS_INVALID_PARAMETER;
+        }
+    if(dwTypeMask & VER_MINORVERSION)
+        switch(dwlConditionMask >> 0*3 & 0x07)
+        {
+            case VER_EQUAL:
+                if(ver.dwMinorVersion != info->dwMinorVersion) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER:
+                if(ver.dwMinorVersion <= info->dwMinorVersion) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER_EQUAL:
+                if(ver.dwMinorVersion < info->dwMinorVersion) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS:
+                if(ver.dwMinorVersion >= info->dwMinorVersion) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS_EQUAL:
+                if(ver.dwMinorVersion > info->dwMinorVersion) return STATUS_REVISION_MISMATCH;
+                break;
+            default:
+                return STATUS_INVALID_PARAMETER;
+        }
+    if(dwTypeMask & VER_SERVICEPACKMAJOR)
+        switch(dwlConditionMask >> 5*3 & 0x07)
+        {
+            case VER_EQUAL:
+                if(ver.wServicePackMajor != info->wServicePackMajor) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER:
+                if(ver.wServicePackMajor <= info->wServicePackMajor) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER_EQUAL:
+                if(ver.wServicePackMajor < info->wServicePackMajor) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS:
+                if(ver.wServicePackMajor >= info->wServicePackMajor) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS_EQUAL:
+                if(ver.wServicePackMajor > info->wServicePackMajor) return STATUS_REVISION_MISMATCH;
+                break;
+            default:
+                return STATUS_INVALID_PARAMETER;
+        }
+    if(dwTypeMask & VER_SERVICEPACKMINOR)
+        switch(dwlConditionMask >> 4*3 & 0x07)
+        {
+            case VER_EQUAL:
+                if(ver.wServicePackMinor != info->wServicePackMinor) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER:
+                if(ver.wServicePackMinor <= info->wServicePackMinor) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_GREATER_EQUAL:
+                if(ver.wServicePackMinor < info->wServicePackMinor) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS:
+                if(ver.wServicePackMinor >= info->wServicePackMinor) return STATUS_REVISION_MISMATCH;
+                break;
+            case VER_LESS_EQUAL:
+                if(ver.wServicePackMinor > info->wServicePackMinor) return STATUS_REVISION_MISMATCH;
+                break;
+            default:
+                return STATUS_INVALID_PARAMETER;
+        }
+
+    return STATUS_SUCCESS;
+}
diff --git a/files/drive.c b/files/drive.c
index acbc93de093358db5c687b4af3521e98b33639f2..6fb0e5c96e0960bcf7807bda282be8ac99fc0761 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -1061,7 +1061,7 @@ static DWORD CDROM_Data_GetSerial(int drive)
     if (offs)
     {
         BYTE buf[2048];
-        OSVERSIONINFOA ovi;
+        RTL_OSVERSIONINFOEXW ovi;
         int i;
 
         lseek(dev, offs, SEEK_SET);
@@ -1071,8 +1071,8 @@ static DWORD CDROM_Data_GetSerial(int drive)
          * Me$$ysoft chose to reverse the serial number in NT4/W2K.
          * It's true and nobody will ever be able to change it.
          */
-        ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
-        GetVersionExA(&ovi);
+        ovi.dwOSVersionInfoSize = sizeof(ovi);
+        RtlGetVersion(&ovi);
         if ((ovi.dwPlatformId == VER_PLATFORM_WIN32_NT) &&  (ovi.dwMajorVersion >= 4))
         {
             b0 = 3; b1 = 2; b2 = 1; b3 = 0;
@@ -1674,9 +1674,9 @@ BOOL WINAPI GetDiskFreeSpaceExW( LPCWSTR root,
 	       FIXME messages, so don't print the FIXME unless Wine is
 	       actually masquerading as Windows2000. */
 
-            OSVERSIONINFOA ovi;
-	    ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
-	    if (GetVersionExA(&ovi))
+            RTL_OSVERSIONINFOEXW ovi;
+	    ovi.dwOSVersionInfoSize = sizeof(ovi);
+	    if (RtlGetVersion(&ovi))
 	    {
 	      if (ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4)
                   FIXME("no per-user quota support yet\n");
diff --git a/include/winbase.h b/include/winbase.h
index eeb3de46fdfe3d8a6df0b5e8307b8ef3850fb417..a617d93337375cd54aa2542f0ec184743a3ea265 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -833,100 +833,6 @@ typedef DWORD (CALLBACK *LPPROGRESS_ROUTINE)(LARGE_INTEGER, LARGE_INTEGER, LARGE
 #define	FORMAT_MESSAGE_ARGUMENT_ARRAY	0x00002000
 #define	FORMAT_MESSAGE_MAX_WIDTH_MASK	0x000000FF
 
-typedef struct {
-	DWORD dwOSVersionInfoSize;
-	DWORD dwMajorVersion;
-	DWORD dwMinorVersion;
-	DWORD dwBuildNumber;
-	DWORD dwPlatformId;
-	CHAR szCSDVersion[128];
-} OSVERSIONINFOA, *POSVERSIONINFOA, *LPOSVERSIONINFOA;
-
-typedef struct {
-	DWORD dwOSVersionInfoSize;
-	DWORD dwMajorVersion;
-	DWORD dwMinorVersion;
-	DWORD dwBuildNumber;
-	DWORD dwPlatformId;
-	WCHAR szCSDVersion[128];
-} OSVERSIONINFOW, *POSVERSIONINFOW, *LPOSVERSIONINFOW;
-
-DECL_WINELIB_TYPE_AW(OSVERSIONINFO)
-DECL_WINELIB_TYPE_AW(POSVERSIONINFO)
-DECL_WINELIB_TYPE_AW(LPOSVERSIONINFO)
-
-typedef struct {
-	DWORD dwOSVersionInfoSize;
-	DWORD dwMajorVersion;
-	DWORD dwMinorVersion;
-	DWORD dwBuildNumber;
-	DWORD dwPlatformId;
-	CHAR szCSDVersion[128];
-	WORD wServicePackMajor;
-	WORD wServicePackMinor;
-	WORD wSuiteMask;
-	BYTE wProductType;
-	BYTE wReserved;
-} OSVERSIONINFOEXA, *POSVERSIONINFOEXA, *LPOSVERSIONINFOEXA;
-
-typedef struct {
-	DWORD dwOSVersionInfoSize;
-	DWORD dwMajorVersion;
-	DWORD dwMinorVersion;
-	DWORD dwBuildNumber;
-	DWORD dwPlatformId;
-	WCHAR szCSDVersion[128];
-	WORD wServicePackMajor;
-	WORD wServicePackMinor;
-	WORD wSuiteMask;
-	BYTE wProductType;
-	BYTE wReserved;
-} OSVERSIONINFOEXW, *POSVERSIONINFOEXW, *LPOSVERSIONINFOEXW;
-
-DECL_WINELIB_TYPE_AW(OSVERSIONINFOEX)
-DECL_WINELIB_TYPE_AW(POSVERSIONINFOEX)
-DECL_WINELIB_TYPE_AW(LPOSVERSIONINFOEX)
-
-ULONGLONG WINAPI VerSetConditionMask(ULONGLONG,DWORD,BYTE);
-
-#define VER_SET_CONDITION(_m_,_t_,_c_) ((_m_)=VerSetConditionMask((_m_),(_t_),(_c_)))
-
-#define	VER_PLATFORM_WIN32s             	0
-#define	VER_PLATFORM_WIN32_WINDOWS      	1
-#define	VER_PLATFORM_WIN32_NT           	2
-
-#define	VER_MINORVERSION			0x00000001
-#define	VER_MAJORVERSION			0x00000002
-#define	VER_BUILDNUMBER				0x00000004
-#define	VER_PLATFORMID				0x00000008
-#define	VER_SERVICEPACKMINOR			0x00000010
-#define	VER_SERVICEPACKMAJOR			0x00000020
-#define	VER_SUITENAME				0x00000040
-#define	VER_PRODUCT_TYPE			0x00000080
-
-#define	VER_NT_WORKSTATION			1
-#define	VER_NT_DOMAIN_CONTROLLER		2
-#define	VER_NT_SERVER				3
-
-#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_EQUAL				1
-#define	VER_GREATER				2
-#define	VER_GREATER_EQUAL			3
-#define	VER_LESS				4
-#define	VER_LESS_EQUAL				5
-#define	VER_AND					6
-#define	VER_OR					7
-
 typedef struct tagCOMSTAT
 {
     DWORD fCtsHold : 1;
@@ -1102,11 +1008,6 @@ typedef enum _COMPUTER_NAME_FORMAT
 	ComputerNameMax
 } COMPUTER_NAME_FORMAT;
 
-/*DWORD WINAPI GetVersion( void );*/
-BOOL WINAPI GetVersionExA(OSVERSIONINFOA*);
-BOOL WINAPI GetVersionExW(OSVERSIONINFOW*);
-#define GetVersionEx WINELIB_NAME_AW(GetVersionEx)
-
 #define HW_PROFILE_GUIDLEN	39
 #define MAX_PROFILE_LEN		80
 
@@ -1725,7 +1626,10 @@ UINT        WINAPI GetTempFileNameW(LPCWSTR,LPCWSTR,UINT,LPWSTR);
 UINT        WINAPI GetTempPathA(UINT,LPSTR);
 UINT        WINAPI GetTempPathW(UINT,LPWSTR);
 #define     GetTempPath WINELIB_NAME_AW(GetTempPath)
-LONG        WINAPI GetVersion(void);
+DWORD       WINAPI GetVersion(void);
+BOOL        WINAPI GetVersionExA(OSVERSIONINFOA*);
+BOOL        WINAPI GetVersionExW(OSVERSIONINFOW*);
+#define     GetVersionEx WINELIB_NAME_AW(GetVersionEx)
 BOOL        WINAPI GetVolumeInformationA(LPCSTR,LPSTR,DWORD,LPDWORD,LPDWORD,LPDWORD,LPSTR,DWORD);
 BOOL        WINAPI GetVolumeInformationW(LPCWSTR,LPWSTR,DWORD,LPDWORD,LPDWORD,LPDWORD,LPWSTR,DWORD);
 #define     GetVolumeInformation WINELIB_NAME_AW(GetVolumeInformation)
diff --git a/include/windef.h b/include/windef.h
index 765f451615e6ffc7e3713b39e03088b4f15715c8..809fdd3f925e6f6b266247b70d76aeb51ddc7bc4 100644
--- a/include/windef.h
+++ b/include/windef.h
@@ -179,8 +179,6 @@ typedef unsigned long   DWORD,      *PDWORD,   *LPDWORD;
 typedef unsigned long   ULONG,      *PULONG;
 typedef float           FLOAT,      *PFLOAT;
 
-#include <winnt.h>
-
 /* Macros to map Winelib names to the correct implementation name */
 /* Note that Winelib is purely Win32.                             */
 
@@ -202,6 +200,7 @@ typedef float           FLOAT,      *PFLOAT;
 # define DECL_WINELIB_TYPE_AW(type)  typedef WINELIB_NAME_AW(type) type;
 #endif  /* __WINESRC__ */
 
+#include <winnt.h>
 
 /* Polymorphic types */
 
diff --git a/include/wine/winbase16.h b/include/wine/winbase16.h
index 3b889be7de571af48a9859ae57a9053649afdedc..6ec65ce7262dec6844dfe45c982c58e06020449d 100644
--- a/include/wine/winbase16.h
+++ b/include/wine/winbase16.h
@@ -309,7 +309,7 @@ DWORD       WINAPI GetSelectorBase(WORD);
 BOOL16      WINAPI GetStringType16(LCID,DWORD,LPCSTR,INT16,LPWORD);
 UINT16      WINAPI GetSystemDirectory16(LPSTR,UINT16);
 UINT16      WINAPI GetTempFileName16(BYTE,LPCSTR,UINT16,LPSTR);
-LONG        WINAPI GetVersion16(void);
+DWORD       WINAPI GetVersion16(void);
 BOOL16      WINAPI GetVersionEx16(OSVERSIONINFO16*);
 BOOL16      WINAPI GetWinDebugInfo16(LPWINDEBUGINFO16,UINT16);
 UINT16      WINAPI GetWindowsDirectory16(LPSTR,UINT16);
diff --git a/include/winnt.h b/include/winnt.h
index 6dba3e2510a31667d4e00d605f31b6eb6beb87ff..7915d0bf27f8a309f1db07ba0e38c4d716a5b48a 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -3610,4 +3610,98 @@ typedef struct _IO_COUNTERS {
 } IO_COUNTERS;
 typedef IO_COUNTERS *PIO_COUNTERS;
 
+typedef struct {
+	DWORD dwOSVersionInfoSize;
+	DWORD dwMajorVersion;
+	DWORD dwMinorVersion;
+	DWORD dwBuildNumber;
+	DWORD dwPlatformId;
+	CHAR szCSDVersion[128];
+} OSVERSIONINFOA, *POSVERSIONINFOA, *LPOSVERSIONINFOA;
+
+typedef struct {
+	DWORD dwOSVersionInfoSize;
+	DWORD dwMajorVersion;
+	DWORD dwMinorVersion;
+	DWORD dwBuildNumber;
+	DWORD dwPlatformId;
+	WCHAR szCSDVersion[128];
+} OSVERSIONINFOW, *POSVERSIONINFOW, *LPOSVERSIONINFOW, RTL_OSVERSIONINFOW, *PRTL_OSVERSIONINFOW;
+
+DECL_WINELIB_TYPE_AW(OSVERSIONINFO)
+DECL_WINELIB_TYPE_AW(POSVERSIONINFO)
+DECL_WINELIB_TYPE_AW(LPOSVERSIONINFO)
+
+typedef struct {
+	DWORD dwOSVersionInfoSize;
+	DWORD dwMajorVersion;
+	DWORD dwMinorVersion;
+	DWORD dwBuildNumber;
+	DWORD dwPlatformId;
+	CHAR szCSDVersion[128];
+	WORD wServicePackMajor;
+	WORD wServicePackMinor;
+	WORD wSuiteMask;
+	BYTE wProductType;
+	BYTE wReserved;
+} OSVERSIONINFOEXA, *POSVERSIONINFOEXA, *LPOSVERSIONINFOEXA;
+
+typedef struct {
+	DWORD dwOSVersionInfoSize;
+	DWORD dwMajorVersion;
+	DWORD dwMinorVersion;
+	DWORD dwBuildNumber;
+	DWORD dwPlatformId;
+	WCHAR szCSDVersion[128];
+	WORD wServicePackMajor;
+	WORD wServicePackMinor;
+	WORD wSuiteMask;
+	BYTE wProductType;
+	BYTE wReserved;
+} OSVERSIONINFOEXW, *POSVERSIONINFOEXW, *LPOSVERSIONINFOEXW, RTL_OSVERSIONINFOEXW, *PRTL_OSVERSIONINFOEXW;
+
+DECL_WINELIB_TYPE_AW(OSVERSIONINFOEX)
+DECL_WINELIB_TYPE_AW(POSVERSIONINFOEX)
+DECL_WINELIB_TYPE_AW(LPOSVERSIONINFOEX)
+
+ULONGLONG WINAPI VerSetConditionMask(ULONGLONG,DWORD,BYTE);
+
+#define VER_SET_CONDITION(_m_,_t_,_c_) ((_m_)=VerSetConditionMask((_m_),(_t_),(_c_)))
+
+#define VER_PLATFORM_WIN32s                     0
+#define VER_PLATFORM_WIN32_WINDOWS              1
+#define VER_PLATFORM_WIN32_NT                   2
+
+#define	VER_MINORVERSION			0x00000001
+#define	VER_MAJORVERSION			0x00000002
+#define	VER_BUILDNUMBER				0x00000004
+#define	VER_PLATFORMID				0x00000008
+#define	VER_SERVICEPACKMINOR			0x00000010
+#define	VER_SERVICEPACKMAJOR			0x00000020
+#define	VER_SUITENAME				0x00000040
+#define	VER_PRODUCT_TYPE			0x00000080
+
+#define	VER_NT_WORKSTATION			1
+#define	VER_NT_DOMAIN_CONTROLLER		2
+#define	VER_NT_SERVER				3
+
+#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_EQUAL				1
+#define	VER_GREATER				2
+#define	VER_GREATER_EQUAL			3
+#define	VER_LESS				4
+#define	VER_LESS_EQUAL				5
+#define	VER_AND					6
+#define	VER_OR					7
+
 #endif  /* __WINE_WINNT_H */
diff --git a/include/winternl.h b/include/winternl.h
index ecd0964c3542497e327e7bb50c834735583ca88a..8592ee98f336d6566181afca6a2aaf4cda2bad64 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -1147,6 +1147,7 @@ BOOLEAN   WINAPI RtlGetNtProductType(LPDWORD);
 NTSTATUS  WINAPI RtlGetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR,PSID *,PBOOLEAN);
 ULONG     WINAPI RtlGetProcessHeaps(ULONG,HANDLE*);
 NTSTATUS  WINAPI RtlGetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR,PBOOLEAN,PACL *,PBOOLEAN);
+NTSTATUS  WINAPI RtlGetVersion(RTL_OSVERSIONINFOEXW*);
 
 PSID_IDENTIFIER_AUTHORITY WINAPI RtlIdentifierAuthoritySid(PSID);
 PVOID     WINAPI RtlImageDirectoryEntryToData(HMODULE,BOOL,WORD,ULONG *);
@@ -1269,6 +1270,7 @@ NTSTATUS  WINAPI RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR);
 BOOLEAN   WINAPI RtlValidAcl(PACL);
 BOOLEAN   WINAPI RtlValidSid(PSID);
 BOOLEAN   WINAPI RtlValidateHeap(HANDLE,ULONG,LPCVOID);
+NTSTATUS  WINAPI RtlVerifyVersionInfo(const RTL_OSVERSIONINFOEXW*,DWORD,DWORDLONG);
 
 NTSTATUS  WINAPI RtlWalkHeap(HANDLE,PVOID);
 
diff --git a/misc/version.c b/misc/version.c
deleted file mode 100644
index 39a07f605f1e3baeded641f1334e85af3482722d..0000000000000000000000000000000000000000
--- a/misc/version.c
+++ /dev/null
@@ -1,1102 +0,0 @@
-/*
- * Windows and DOS version functions
- *
- * Copyright 1997 Alexandre Julliard
- * Copyright 1997 Marcus Meissner
- * Copyright 1998 Patrik Stridvall
- * Copyright 1998,2003 Andreas Mohr
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "config.h"
-#include "wine/port.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include "ntstatus.h"
-#include "windef.h"
-#include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winreg.h"
-#include "winternl.h"
-#include "winerror.h"
-#include "wine/winbase16.h"
-#include "module.h"
-#include "wine/unicode.h"
-#include "wine/debug.h"
-#include "ntdll_misc.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ver);
-
-typedef enum
-{
-    WIN20,   /* Windows 2.0 */
-    WIN30,   /* Windows 3.0 */
-    WIN31,   /* Windows 3.1 */
-    WIN95,   /* Windows 95 */
-    WIN98,   /* Windows 98 */
-    WINME,   /* Windows Me */
-    NT351,   /* Windows NT 3.51 */
-    NT40,    /* Windows NT 4.0 */
-    NT2K,    /* Windows 2000 */
-    WINXP,   /* Windows XP */
-    WIN2K3,  /* Windows 2003 */
-    NB_WINDOWS_VERSIONS
-} WINDOWS_VERSION;
-
-typedef struct
-{
-    char             human_readable[32];
-    LONG             getVersion16;
-    LONG             getVersion32;
-    OSVERSIONINFOEXA getVersionEx;
-} VERSION_DATA;
-
-/* FIXME: compare values below with original and fix.
- * An *excellent* win9x version page (ALL versions !)
- * can be found at members.aol.com/axcel216/ver.htm */
-static VERSION_DATA VersionData[NB_WINDOWS_VERSIONS] =
-{
-    /* WIN20 FIXME: verify values */
-    {
-	"Windows 2.0",
-	MAKELONG( 0x0002, 0x0303 ), /* assume DOS 3.3 */
-	MAKELONG( 0x0002, 0x8000 ),
-	{
-	    /* yes, sizeof(OSVERSIONINFOA) is correct here
-	     * (in case of OSVERSIONINFOEXA application request,
-	     * we adapt it dynamically). */
-            sizeof(OSVERSIONINFOA), 2, 0, 0,
-            VER_PLATFORM_WIN32s, "Win32s 1.3",
-	    0, 0, 0, 0, 0
-	}
-    },
-    /* WIN30 FIXME: verify values */
-    {
-	"Windows 3.0",
-	MAKELONG( 0x0003, 0x0500 ), /* assume DOS 5.00 */
-	MAKELONG( 0x0003, 0x8000 ),
-	{
-            sizeof(OSVERSIONINFOA), 3, 0, 0,
-            VER_PLATFORM_WIN32s, "Win32s 1.3",
-	    0, 0, 0, 0, 0
-	}
-    },
-    /* WIN31 */
-    {
-	"Windows 3.1",
-	MAKELONG( 0x0a03, 0x0616 ), /* DOS 6.22 */
-	MAKELONG( 0x0a03, 0x8000 ),
-	{
-            sizeof(OSVERSIONINFOA), 3, 10, 0,
-            VER_PLATFORM_WIN32s, "Win32s 1.3",
-	    0, 0, 0, 0, 0
-	}
-    },
-    /* WIN95 */
-    {
-	"Windows 95",
-        0x07005F03,
-        0xC0000004,
-        {
-            /* Win95:       4, 0, 0x40003B6, ""
-             * Win95sp1:    4, 0, 0x40003B6, " A " (according to doc)
-             * Win95osr2:   4, 0, 0x4000457, " B " (according to doc)
-             * Win95osr2.1: 4, 3, 0x40304BC, " B " (according to doc)
-             * Win95osr2.5: 4, 3, 0x40304BE, " C " (according to doc)
-             * Win95a/b can be discerned via regkey SubVersionNumber
-             * See also:
-             * http://support.microsoft.com/support/kb/articles/q158/2/38.asp
-             */
-            sizeof(OSVERSIONINFOA), 4, 0, 0x40003B6,
-            VER_PLATFORM_WIN32_WINDOWS, "",
-	    0, 0, 0, 0, 0
-        }
-    },
-    /* WIN98 (second edition) */
-    {
-	"Windows 98 SE",
-        0x070A5F03,
-        0xC0000A04,
-        {
-            /* Win98:   4, 10, 0x40A07CE, " "   4.10.1998
-             * Win98SE: 4, 10, 0x40A08AE, " A " 4.10.2222
-             */
-            sizeof(OSVERSIONINFOA), 4, 10, 0x40A08AE,
-            VER_PLATFORM_WIN32_WINDOWS, " A ",
-	    0, 0, 0, 0, 0
-        }
-    },
-    /* WINME */
-    {
-	"Windows ME",
-        0x08005F03,
-        0xC0005A04,
-        {
-            sizeof(OSVERSIONINFOA), 4, 90, 0x45A0BB8,
-            VER_PLATFORM_WIN32_WINDOWS, " ",
-	    0, 0, 0, 0, 0
-        }
-    },
-    /* NT351 */
-    {
-	"Windows NT 3.51",
-        0x05000A03,
-        0x04213303,
-        {
-            sizeof(OSVERSIONINFOA), 3, 51, 0x421,
-            VER_PLATFORM_WIN32_NT, "Service Pack 2",
-	    0, 0, 0, 0, 0
-        }
-    },
-    /* NT40 */
-    {
-	"Windows NT 4.0",
-        0x05000A03,
-        0x05650004,
-        {
-            sizeof(OSVERSIONINFOA), 4, 0, 0x565,
-            VER_PLATFORM_WIN32_NT, "Service Pack 6",
-	    6, 0, 0, VER_NT_WORKSTATION, 0
-        }
-    },
-    /* NT2K */
-    {
-	"Windows 2000",
-        0x05005F03,
-        0x08930005,
-        {
-            sizeof(OSVERSIONINFOA), 5, 0, 0x893,
-            VER_PLATFORM_WIN32_NT, "Service Pack 3",
-            3, 0, 0, VER_NT_WORKSTATION, 30 /* FIXME: Great, a reserved field with a value! */
-        }
-    },
-    /* WINXP */
-    {
-	"Windows XP",
-        0x05005F03, /* Assuming DOS 5 like the other NT */
-        0x0A280105,
-        {
-            sizeof(OSVERSIONINFOA), 5, 1, 0xA28,
-            VER_PLATFORM_WIN32_NT, "Service Pack 1",
-            1, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 30 /* FIXME: Great, a reserved field with a value! */
-        }
-    },
-    /* WIN2K3 */
-    {
-	"Windows 2003",
-        0x05005F03, /* Assuming DOS 5 like the other NT */
-        0x0ECE0205,
-        {
-            sizeof(OSVERSIONINFOA), 5, 2, 0xECE,
-            VER_PLATFORM_WIN32_NT, "",
-            0, 0, VER_SUITE_SINGLEUSERTS, VER_NT_SERVER, 0
-        }
-    }
-};
-
-static const char *WinVersionNames[NB_WINDOWS_VERSIONS] =
-{ /* no spaces in here ! */
-    "win20",
-    "win30",
-    "win31",
-    "win95",
-    "win98",
-    "winme",
-    "nt351",
-    "nt40",
-    "win2000,win2k,nt2k,nt2000",
-    "winxp",
-    "win2003,win2k3"
-};
-
-/* if one of the following dlls is importing ntdll the windows
-version autodetection switches wine to unicode (nt 3.51 or 4.0) */
-static char * special_dlls[] =
-{
-	"comdlg32.dll",
-	"comctl32.dll",
-	"shell32.dll",
-	"ole32.dll",
-	"rpcrt4.dll",
-	NULL
-};
-
-/* the current version has not been autodetected but forced via cmdline */
-static BOOL versionForced = FALSE;
-static WINDOWS_VERSION forcedWinVersion = WIN31; /* init value irrelevant */
-
-/**********************************************************************
- *         VERSION_ParseWinVersion
- */
-static void VERSION_ParseWinVersion( const char *arg )
-{
-    int i, len;
-    const char *pCurr, *p;
-    for (i = 0; i < NB_WINDOWS_VERSIONS; i++)
-    {
-        pCurr = WinVersionNames[i];
-        /* iterate through all winver aliases separated by comma */
-        do {
-            p = strchr(pCurr, ',');
-            len = p ? (int)p - (int)pCurr : strlen(pCurr);
-            if ( (!strncmp( pCurr, arg, len )) && (arg[len] == '\0') )
-            {
-                forcedWinVersion = (WINDOWS_VERSION)i;
-                versionForced = TRUE;
-                return;
-            }
-            pCurr = p+1;
-        } while (p);
-    }
-    MESSAGE("Invalid Windows version value '%s' specified in config file.\n", arg );
-    MESSAGE("Valid versions are:" );
-    for (i = 0; i < NB_WINDOWS_VERSIONS; i++)
-    {
-        /* only list the first, "official" alias in case of aliases */
-        pCurr = WinVersionNames[i];
-        p = strchr(pCurr, ',');
-        len = (p) ? (int)p - (int)pCurr : strlen(pCurr);
-
-        MESSAGE(" '%.*s'%c", len, pCurr,
-                (i == NB_WINDOWS_VERSIONS - 1) ? '\n' : ',' );
-    }
-    ExitProcess(1);
-}
-
-
-/**********************************************************************
- *         VERSION_ParseDosVersion
- */
-static void VERSION_ParseDosVersion( const char *arg )
-{
-    int hi, lo;
-    if (sscanf( arg, "%d.%d", &hi, &lo ) == 2)
-    {
-        VersionData[WIN31].getVersion16 =
-            MAKELONG(LOWORD(VersionData[WIN31].getVersion16),
-                     (hi<<8) + lo);
-    }
-    else
-    {
-        MESSAGE("Wrong format for DOS version in config file. Use \"x.xx\"\n");
-        ExitProcess(1);
-    }
-}
-
-
-/**********************************************************************
- *         VERSION_ParseVersion
- *
- * Parse the contents of the Version key.
- */
-static void VERSION_ParseVersion( HKEY hkey, BOOL *got_win_ver, BOOL *got_dos_ver )
-{
-    static const WCHAR WindowsW[] = {'W','i','n','d','o','w','s',0};
-    static const WCHAR DosW[] = {'D','O','S',0};
-
-    UNICODE_STRING valueW;
-    char tmp[64], buffer[50];
-    KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)tmp;
-    DWORD count, len;
-
-    if (!*got_win_ver)
-    {
-        RtlInitUnicodeString( &valueW, WindowsW );
-        if (!NtQueryValueKey( hkey, &valueW, KeyValuePartialInformation, tmp, sizeof(tmp), &count ))
-        {
-            RtlUnicodeToMultiByteN( buffer, sizeof(buffer)-1, &len,
-                                    (WCHAR *)info->Data, info->DataLength );
-            buffer[len] = 0;
-            VERSION_ParseWinVersion( buffer );
-            TRACE( "got win version %s\n", WinVersionNames[forcedWinVersion] );
-            *got_win_ver = TRUE;
-        }
-    }
-    if (!*got_dos_ver)
-    {
-        RtlInitUnicodeString( &valueW, DosW );
-        if (!NtQueryValueKey( hkey, &valueW, KeyValuePartialInformation, tmp, sizeof(tmp), &count ))
-        {
-            RtlUnicodeToMultiByteN( buffer, sizeof(buffer)-1, &len,
-                                    (WCHAR *)info->Data, info->DataLength );
-            buffer[len] = 0;
-            VERSION_ParseDosVersion( buffer );
-            TRACE( "got dos version %lx\n", VersionData[WIN31].getVersion16 );
-            *got_dos_ver = TRUE;
-        }
-    }
-}
-
-
-/**********************************************************************
- *         VERSION_Init
- */
-void VERSION_Init( const char *appname )
-{
-    OBJECT_ATTRIBUTES attr;
-    UNICODE_STRING nameW;
-    HKEY hkey, config_key;
-    BOOL got_win_ver = FALSE, got_dos_ver = FALSE;
-    static const WCHAR configW[] = {'M','a','c','h','i','n','e','\\',
-                                    'S','o','f','t','w','a','r','e','\\',
-                                    'W','i','n','e','\\',
-                                    'W','i','n','e','\\',
-                                    'C','o','n','f','i','g',0};
-    static const WCHAR appdefaultsW[] = {'A','p','p','D','e','f','a','u','l','t','s','\\',0};
-    static const WCHAR versionW[] = {'\\','V','e','r','s','i','o','n',0};
-
-    attr.Length = sizeof(attr);
-    attr.RootDirectory = 0;
-    attr.ObjectName = &nameW;
-    attr.Attributes = 0;
-    attr.SecurityDescriptor = NULL;
-    attr.SecurityQualityOfService = NULL;
-    RtlInitUnicodeString( &nameW, configW );
-
-    if (NtOpenKey( &config_key, KEY_ALL_ACCESS, &attr )) return;
-    attr.RootDirectory = config_key;
-
-    /* open AppDefaults\\appname\\Version key */
-    if (appname && *appname)
-    {
-        const char *p;
-        DWORD len;
-        WCHAR appversion[MAX_PATH+20];
-
-        if ((p = strrchr( appname, '/' ))) appname = p + 1;
-        if ((p = strrchr( appname, '\\' ))) appname = p + 1;
-
-        strcpyW( appversion, appdefaultsW );
-        len = strlenW(appversion);
-        RtlMultiByteToUnicodeN( appversion + len, sizeof(appversion) - len*sizeof(WCHAR),
-                                &len, appname, strlen(appname)+1 );
-        strcatW( appversion, versionW );
-        TRACE( "getting version from %s\n", debugstr_w(appversion) );
-        RtlInitUnicodeString( &nameW, appversion );
-
-        if (!NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ))
-        {
-            VERSION_ParseVersion( hkey, &got_win_ver, &got_dos_ver );
-            NtClose( hkey );
-        }
-        if (got_win_ver && got_dos_ver) goto done;
-    }
-
-    TRACE( "getting default version\n" );
-    RtlInitUnicodeString( &nameW, versionW + 1 );
-    if (!NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ))
-    {
-        VERSION_ParseVersion( hkey, &got_win_ver, &got_dos_ver );
-        NtClose( hkey );
-    }
-
- done:
-    NtClose( config_key );
-}
-
-
-/**********************************************************************
- *	VERSION_GetSystemDLLVersion
- *
- * This function tries to figure out if a given (native) dll comes from
- * win95/98 or winnt. Since all values in the OptionalHeader are not a
- * usable hint, we test if a dll imports the ntdll.
- * This is at least working for all system dlls like comctl32, comdlg32 and
- * shell32.
- * If you have a better idea to figure this out...
- */
-static DWORD VERSION_GetSystemDLLVersion( HMODULE hmod )
-{
-    DWORD size;
-    IMAGE_IMPORT_DESCRIPTOR *pe_imp;
-
-    if ((pe_imp = RtlImageDirectoryEntryToData( hmod, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size )))
-    {
-        for ( ; pe_imp->Name; pe_imp++)
-        {
-	    char * name = (char *)hmod + (unsigned int)pe_imp->Name;
-	    TRACE("%s\n", name);
-
-	    if (!strncasecmp(name, "ntdll", 5))
-	    {
-	      switch(RtlImageNtHeader(hmod)->OptionalHeader.MajorOperatingSystemVersion) {
-		  case 3:
-			  MESSAGE("WARNING: very old native DLL (NT 3.x) used, might cause instability.\n");
-			  return NT351;
-		  case 4: return NT40;
-		  case 5: return NT2K;
-		  case 6: return WINXP;
-		  case 7: return WIN2K3; /* FIXME: Not sure, should be verified with a Win2K3 dll */
-		  default:
-			  FIXME("Unknown DLL OS version, please report !!\n");
-			  return WIN2K3;
-	      }
-	    }
-        }
-    }
-    return WIN95;
-}
-/**********************************************************************
- *	VERSION_GetLinkedDllVersion
- *
- * Some version data (not reliable!):
- * linker/OS/image/subsys
- *
- * x.xx/1.00/0.00/3.10	Win32s		(any version ?)
- * 2.39/1.00/0.00/3.10	Win32s		freecell.exe (any version)
- * 2.50/1.00/4.00/4.00	Win32s 1.30	winhlp32.exe
- * 2.60/3.51/3.51/3.51	NT351SP5	system dlls
- * 2.60/3.51/3.51/4.00	NT351SP5	comctl32 dll
- * 2.xx/1.00/0.00/4.00	Win95 		system files
- * x.xx/4.00/0.00/4.00	Win95		most applications
- * 3.10/4.00/0.00/4.00	Win98		notepad
- * x.xx/5.00/5.00/4.00	Win98 		system dlls (e.g. comctl32.dll)
- * x.xx/4.00/4.00/4.00	NT 4 		most apps
- * 5.12/5.00/5.00/4.00	NT4+IE5		comctl32.dll
- * 5.12/5.00/5.00/4.00	Win98		calc
- * x.xx/5.00/5.00/4.00	win95/win98/NT4	IE5 files
- */
-static DWORD VERSION_GetLinkedDllVersion(void)
-{
-	DWORD WinVersion = NB_WINDOWS_VERSIONS;
-	PIMAGE_OPTIONAL_HEADER ophd;
-        IMAGE_NT_HEADERS *nt;
-        ULONG       count, required;
-        SYSTEM_MODULE_INFORMATION*  smi;
-
-	/* First check the native dlls provided. These have to be
-	from one windows version */
-        smi = (SYSTEM_MODULE_INFORMATION*)&count;
-        LdrQueryProcessModuleInformation(smi, sizeof(count), &required);
-        smi = RtlAllocateHeap(ntdll_get_process_heap(), 0, required);
-        if (smi)
-        {
-            if (LdrQueryProcessModuleInformation(smi, required, NULL) == STATUS_SUCCESS)
-            {
-                int i, k;
-                for (k = 0; k < smi->ModulesCount; k++)
-                {
-                    nt = RtlImageNtHeader(smi->Modules[k].ImageBaseAddress);
-                    ophd = &nt->OptionalHeader;
-
-                    TRACE("%s: %02x.%02x/%02x.%02x/%02x.%02x/%02x.%02x\n",
-                          &smi->Modules[k].Name[smi->Modules[k].NameOffset],
-                          ophd->MajorLinkerVersion, ophd->MinorLinkerVersion,
-                          ophd->MajorOperatingSystemVersion, ophd->MinorOperatingSystemVersion,
-                          ophd->MajorImageVersion, ophd->MinorImageVersion,
-                          ophd->MajorSubsystemVersion, ophd->MinorSubsystemVersion);
-
-                    /* test if it is an external (native) dll */
-                    if (smi->Modules[k].Flags & LDR_WINE_INTERNAL) continue;
-
-                    for (i = 0; special_dlls[i]; i++)
-                    {
-                        /* test if it is a special dll */
-                        if (!strcasecmp(&smi->Modules[k].Name[smi->Modules[k].NameOffset], special_dlls[i]))
-                        {
-                            DWORD DllVersion = VERSION_GetSystemDLLVersion(smi->Modules[k].ImageBaseAddress);
-                            if (WinVersion == NB_WINDOWS_VERSIONS)
-                                WinVersion = DllVersion;
-                            else 
-                            {
-                                if (WinVersion != DllVersion) {
-                                    ERR("You mixed system DLLs from different windows versions! Expect a crash! (%s: expected version '%s', but is '%s')\n",
-                                        &smi->Modules[k].Name[smi->Modules[k].NameOffset],
-                                        VersionData[WinVersion].getVersionEx.szCSDVersion,
-                                        VersionData[DllVersion].getVersionEx.szCSDVersion);
-                                    return WIN20; /* this may let the exe exiting */
-                                }
-                            }
-                            break;
-                        }
-                    }
-                }
-            }
-            RtlFreeHeap(ntdll_get_process_heap(), 0, smi);
-        }
-
-	if(WinVersion != NB_WINDOWS_VERSIONS) return WinVersion;
-
-	/* we are using no external system dlls, look at the exe */
-        nt = RtlImageNtHeader(GetModuleHandleA(NULL));
-        ophd = &nt->OptionalHeader;
-
-	TRACE("%02x.%02x/%02x.%02x/%02x.%02x/%02x.%02x\n",
-	    ophd->MajorLinkerVersion, ophd->MinorLinkerVersion,
-	    ophd->MajorOperatingSystemVersion, ophd->MinorOperatingSystemVersion,
-	    ophd->MajorImageVersion, ophd->MinorImageVersion,
-	    ophd->MajorSubsystemVersion, ophd->MinorSubsystemVersion);
-
-	/* special nt 3.51 */
-	if (3 == ophd->MajorOperatingSystemVersion && 51 == ophd->MinorOperatingSystemVersion)
-	{
-	    return NT351;
-	}
-
-	/* the MajorSubsystemVersion is the only usable sign */
-	if (ophd->MajorSubsystemVersion < 4)
-	{
-	  if ( ophd->MajorOperatingSystemVersion == 1
-	    && ophd->MinorOperatingSystemVersion == 0)
-	  {
-	    return WIN31; /* win32s */
-	  }
-
-	  if (ophd->Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
-	    return NT351; /* FIXME: NT 3.1, not tested */
-	  else
-	    return WIN95;
-	}
-
-	return WIN95;
-}
-
-/**********************************************************************
- *         VERSION_GetVersion
- *
- * WARNING !!!
- * Don't call this function too early during the Wine init,
- * as pdb->exe_modref (required by VERSION_GetImageVersion()) might still
- * be NULL in such cases, which causes the winver to ALWAYS be detected
- * as WIN31.
- * And as we cache the winver once it has been determined, this is bad.
- * This can happen much easier than you might think, as this function
- * is called by EVERY GetVersion*() API !
- *
- */
-static WINDOWS_VERSION VERSION_GetVersion(void)
-{
-    static WORD winver = 0xffff;
-
-    if (versionForced) return forcedWinVersion;  /* user has overridden any sensible checks */
-
-    if (winver == 0xffff) /* to be determined */
-    {
-        WINDOWS_VERSION retver = VERSION_GetLinkedDllVersion();
-
-        /* cache determined value, but do not store in case of WIN31 */
-        if (retver != WIN31) winver = retver;
-        return retver;
-    }
-    return winver;
-}
-
-
-/***********************************************************************
- *         GetVersion   (KERNEL.3)
- */
-LONG WINAPI GetVersion16(void)
-{
-    WINDOWS_VERSION ver = VERSION_GetVersion();
-    TRACE("<-- %s (%s)\n", VersionData[ver].human_readable, VersionData[ver].getVersionEx.szCSDVersion);
-    return VersionData[ver].getVersion16;
-}
-
-
-/***********************************************************************
- *         GetVersion   (KERNEL32.@)
- */
-LONG WINAPI GetVersion(void)
-{
-    WINDOWS_VERSION ver = VERSION_GetVersion();
-    TRACE("<-- %s (%s)\n", VersionData[ver].human_readable, VersionData[ver].getVersionEx.szCSDVersion);
-    return VersionData[ver].getVersion32;
-}
-
-
-/***********************************************************************
- *         GetVersionEx   (KERNEL.149)
- */
-BOOL16 WINAPI GetVersionEx16(OSVERSIONINFO16 *v)
-{
-    WINDOWS_VERSION ver = VERSION_GetVersion();
-    if (v->dwOSVersionInfoSize < sizeof(OSVERSIONINFO16))
-    {
-        WARN("wrong OSVERSIONINFO size from app\n");
-        SetLastError(ERROR_INSUFFICIENT_BUFFER);
-        return FALSE;
-    }
-    v->dwMajorVersion = VersionData[ver].getVersionEx.dwMajorVersion;
-    v->dwMinorVersion = VersionData[ver].getVersionEx.dwMinorVersion;
-    v->dwBuildNumber  = VersionData[ver].getVersionEx.dwBuildNumber;
-    v->dwPlatformId   = VersionData[ver].getVersionEx.dwPlatformId;
-    strcpy( v->szCSDVersion, VersionData[ver].getVersionEx.szCSDVersion );
-    TRACE("<-- %s (%s)\n", VersionData[ver].human_readable, VersionData[ver].getVersionEx.szCSDVersion);
-    return TRUE;
-}
-
-
-/***********************************************************************
- *         GetVersionExA   (KERNEL32.@)
- */
-BOOL WINAPI GetVersionExA(OSVERSIONINFOA *v)
-{
-    WINDOWS_VERSION ver = VERSION_GetVersion();
-    LPOSVERSIONINFOEXA vex;
-
-    if (v->dwOSVersionInfoSize != sizeof(OSVERSIONINFOA) &&
-	v->dwOSVersionInfoSize != sizeof(OSVERSIONINFOEXA))
-    {
-        WARN("wrong OSVERSIONINFO size from app (got: %ld, expected: %d or %d)\n",
-                        v->dwOSVersionInfoSize, sizeof(OSVERSIONINFOA),
-			sizeof(OSVERSIONINFOEXA));
-        SetLastError(ERROR_INSUFFICIENT_BUFFER);
-        return FALSE;
-    }
-    v->dwMajorVersion = VersionData[ver].getVersionEx.dwMajorVersion;
-    v->dwMinorVersion = VersionData[ver].getVersionEx.dwMinorVersion;
-    v->dwBuildNumber  = VersionData[ver].getVersionEx.dwBuildNumber;
-    v->dwPlatformId   = VersionData[ver].getVersionEx.dwPlatformId;
-    strcpy( v->szCSDVersion, VersionData[ver].getVersionEx.szCSDVersion );
-    if(v->dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXA)) {
-	vex = (LPOSVERSIONINFOEXA) v;
-	vex->wServicePackMajor = VersionData[ver].getVersionEx.wServicePackMajor;
-	vex->wServicePackMinor = VersionData[ver].getVersionEx.wServicePackMinor;
-	vex->wSuiteMask = VersionData[ver].getVersionEx.wSuiteMask;
-	vex->wProductType = VersionData[ver].getVersionEx.wProductType;
-    }
-    TRACE("<-- %s (%s)\n", VersionData[ver].human_readable, VersionData[ver].getVersionEx.szCSDVersion);
-    return TRUE;
-}
-
-
-/***********************************************************************
- *         GetVersionExW   (KERNEL32.@)
- */
-BOOL WINAPI GetVersionExW(OSVERSIONINFOW *v)
-{
-    WINDOWS_VERSION ver = VERSION_GetVersion();
-    LPOSVERSIONINFOEXW vex;
-
-    if (v->dwOSVersionInfoSize != sizeof(OSVERSIONINFOW) &&
-	v->dwOSVersionInfoSize != sizeof(OSVERSIONINFOEXW))
-    {
-        WARN("wrong OSVERSIONINFO size from app (got: %ld, expected: %d or %d)\n",
-			v->dwOSVersionInfoSize, sizeof(OSVERSIONINFOW),
-			sizeof(OSVERSIONINFOEXW));
-        SetLastError(ERROR_INSUFFICIENT_BUFFER);
-        return FALSE;
-    }
-    v->dwMajorVersion = VersionData[ver].getVersionEx.dwMajorVersion;
-    v->dwMinorVersion = VersionData[ver].getVersionEx.dwMinorVersion;
-    v->dwBuildNumber  = VersionData[ver].getVersionEx.dwBuildNumber;
-    v->dwPlatformId   = VersionData[ver].getVersionEx.dwPlatformId;
-    MultiByteToWideChar( CP_ACP, 0, VersionData[ver].getVersionEx.szCSDVersion, -1,
-                         v->szCSDVersion, sizeof(v->szCSDVersion)/sizeof(WCHAR) );
-    if(v->dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXW)) {
-	vex = (LPOSVERSIONINFOEXW) v;
-	vex->wServicePackMajor = VersionData[ver].getVersionEx.wServicePackMajor;
-	vex->wServicePackMinor = VersionData[ver].getVersionEx.wServicePackMinor;
-	vex->wSuiteMask = VersionData[ver].getVersionEx.wSuiteMask;
-	vex->wProductType = VersionData[ver].getVersionEx.wProductType;
-    }
-    TRACE("<-- %s (%s)\n", VersionData[ver].human_readable, VersionData[ver].getVersionEx.szCSDVersion);
-    return TRUE;
-}
-
-
-/******************************************************************************
- *        VerifyVersionInfoA   (KERNEL32.@)
- */
-BOOL WINAPI VerifyVersionInfoA( LPOSVERSIONINFOEXA lpVersionInfo, DWORD dwTypeMask,
-                                DWORDLONG dwlConditionMask)
-{
-    OSVERSIONINFOEXW verW;
-
-    verW.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
-    verW.dwMajorVersion = lpVersionInfo->dwMajorVersion;
-    verW.dwMinorVersion = lpVersionInfo->dwMinorVersion;
-    verW.dwBuildNumber = lpVersionInfo->dwBuildNumber;
-    verW.dwPlatformId = lpVersionInfo->dwPlatformId;
-    verW.wServicePackMajor = lpVersionInfo->wServicePackMajor;
-    verW.wServicePackMinor = lpVersionInfo->wServicePackMinor;
-    verW.wSuiteMask = lpVersionInfo->wSuiteMask;
-    verW.wProductType = lpVersionInfo->wProductType;
-    verW.wReserved = lpVersionInfo->wReserved;
-
-    return VerifyVersionInfoW(&verW, dwTypeMask, dwlConditionMask);
-}
-
-
-/******************************************************************************
- *        VerifyVersionInfoW   (KERNEL32.@)
- */
-BOOL WINAPI VerifyVersionInfoW( LPOSVERSIONINFOEXW lpVersionInfo, DWORD dwTypeMask,
-                                DWORDLONG dwlConditionMask)
-{
-    OSVERSIONINFOEXW ver;
-    BOOL res, error_set;
-
-    FIXME("(%p,%lu,%llx): Not all cases correctly implemented yet\n", lpVersionInfo, dwTypeMask, dwlConditionMask);
-    /* FIXME:
-	- Check the following special case on Windows (various versions):
-	  o lp->wSuiteMask == 0 and ver.wSuiteMask != 0 and VER_AND/VER_OR
-	  o lp->dwOSVersionInfoSize != sizeof(OSVERSIONINFOEXW)
-	- MSDN talks about some tests being impossible. Check what really happens.
-     */
-
-    ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
-    if(!GetVersionExW((LPOSVERSIONINFOW) &ver))
-	return FALSE;
-
-    res = TRUE;
-    error_set = FALSE;
-    if(!(dwTypeMask && dwlConditionMask)) {
-	res = FALSE;
-	SetLastError(ERROR_BAD_ARGUMENTS);
-	error_set = TRUE;
-    }
-    if(dwTypeMask & VER_PRODUCT_TYPE)
-	switch(dwlConditionMask >> 7*3 & 0x07) {
-	    case VER_EQUAL:
-		if(ver.wProductType != lpVersionInfo->wProductType)
-		    res = FALSE;
-		break;
-	    case VER_GREATER:
-		if(ver.wProductType <= lpVersionInfo->wProductType)
-		    res = FALSE;
-		break;
-	    case VER_GREATER_EQUAL:
-		if(ver.wProductType < lpVersionInfo->wProductType)
-		    res = FALSE;
-		break;
-	    case VER_LESS:
-		if(ver.wProductType >= lpVersionInfo->wProductType)
-		    res = FALSE;
-		break;
-	    case VER_LESS_EQUAL:
-		if(ver.wProductType > lpVersionInfo->wProductType)
-		    res = FALSE;
-		break;
-	    default:
-	        res = FALSE;
-		SetLastError(ERROR_BAD_ARGUMENTS);
-		error_set = TRUE;
-	}
-    if(dwTypeMask & VER_SUITENAME && res)
-	switch(dwlConditionMask >> 6*3 & 0x07) {
-	    case VER_AND:
-		if((lpVersionInfo->wSuiteMask & ver.wSuiteMask) != lpVersionInfo->wSuiteMask)
-		    res = FALSE;
-		break;
-	    case VER_OR:
-		if(!(lpVersionInfo->wSuiteMask & ver.wSuiteMask) && lpVersionInfo->wSuiteMask)
-		    res = FALSE;
-		break;
-	    default:
-	        res = FALSE;
-		SetLastError(ERROR_BAD_ARGUMENTS);
-		error_set = TRUE;
-	}
-    if(dwTypeMask & VER_PLATFORMID && res)
-	switch(dwlConditionMask >> 3*3 & 0x07) {
-	    case VER_EQUAL:
-		if(ver.dwPlatformId != lpVersionInfo->dwPlatformId)
-		    res = FALSE;
-		break;
-	    case VER_GREATER:
-		if(ver.dwPlatformId <= lpVersionInfo->dwPlatformId)
-		    res = FALSE;
-		break;
-	    case VER_GREATER_EQUAL:
-		if(ver.dwPlatformId < lpVersionInfo->dwPlatformId)
-		    res = FALSE;
-		break;
-	    case VER_LESS:
-		if(ver.dwPlatformId >= lpVersionInfo->dwPlatformId)
-		    res = FALSE;
-		break;
-	    case VER_LESS_EQUAL:
-		if(ver.dwPlatformId > lpVersionInfo->dwPlatformId)
-		    res = FALSE;
-		break;
-	    default:
-	        res = FALSE;
-		SetLastError(ERROR_BAD_ARGUMENTS);
-		error_set = TRUE;
-	}
-    if(dwTypeMask & VER_BUILDNUMBER && res)
-	switch(dwlConditionMask >> 2*3 & 0x07) {
-	    case VER_EQUAL:
-		if(ver.dwBuildNumber != lpVersionInfo->dwBuildNumber)
-		    res = FALSE;
-		break;
-	    case VER_GREATER:
-		if(ver.dwBuildNumber <= lpVersionInfo->dwBuildNumber)
-		    res = FALSE;
-		break;
-	    case VER_GREATER_EQUAL:
-		if(ver.dwBuildNumber < lpVersionInfo->dwBuildNumber)
-		    res = FALSE;
-		break;
-	    case VER_LESS:
-		if(ver.dwBuildNumber >= lpVersionInfo->dwBuildNumber)
-		    res = FALSE;
-		break;
-	    case VER_LESS_EQUAL:
-		if(ver.dwBuildNumber > lpVersionInfo->dwBuildNumber)
-		    res = FALSE;
-		break;
-	    default:
-	        res = FALSE;
-		SetLastError(ERROR_BAD_ARGUMENTS);
-		error_set = TRUE;
-	}
-    if(dwTypeMask & VER_MAJORVERSION && res)
-	switch(dwlConditionMask >> 1*3 & 0x07) {
-	    case VER_EQUAL:
-		if(ver.dwMajorVersion != lpVersionInfo->dwMajorVersion)
-		    res = FALSE;
-		break;
-	    case VER_GREATER:
-		if(ver.dwMajorVersion <= lpVersionInfo->dwMajorVersion)
-		    res = FALSE;
-		break;
-	    case VER_GREATER_EQUAL:
-		if(ver.dwMajorVersion < lpVersionInfo->dwMajorVersion)
-		    res = FALSE;
-		break;
-	    case VER_LESS:
-		if(ver.dwMajorVersion >= lpVersionInfo->dwMajorVersion)
-		    res = FALSE;
-		break;
-	    case VER_LESS_EQUAL:
-		if(ver.dwMajorVersion > lpVersionInfo->dwMajorVersion)
-		    res = FALSE;
-		break;
-	    default:
-	        res = FALSE;
-		SetLastError(ERROR_BAD_ARGUMENTS);
-		error_set = TRUE;
-	}
-    if(dwTypeMask & VER_MINORVERSION && res)
-	switch(dwlConditionMask >> 0*3 & 0x07) {
-	    case VER_EQUAL:
-		if(ver.dwMinorVersion != lpVersionInfo->dwMinorVersion)
-		    res = FALSE;
-		break;
-	    case VER_GREATER:
-		if(ver.dwMinorVersion <= lpVersionInfo->dwMinorVersion)
-		    res = FALSE;
-		break;
-	    case VER_GREATER_EQUAL:
-		if(ver.dwMinorVersion < lpVersionInfo->dwMinorVersion)
-		    res = FALSE;
-		break;
-	    case VER_LESS:
-		if(ver.dwMinorVersion >= lpVersionInfo->dwMinorVersion)
-		    res = FALSE;
-		break;
-	    case VER_LESS_EQUAL:
-		if(ver.dwMinorVersion > lpVersionInfo->dwMinorVersion)
-		    res = FALSE;
-		break;
-	    default:
-	        res = FALSE;
-		SetLastError(ERROR_BAD_ARGUMENTS);
-		error_set = TRUE;
-	}
-    if(dwTypeMask & VER_SERVICEPACKMAJOR && res)
-	switch(dwlConditionMask >> 5*3 & 0x07) {
-	    case VER_EQUAL:
-		if(ver.wServicePackMajor != lpVersionInfo->wServicePackMajor)
-		    res = FALSE;
-		break;
-	    case VER_GREATER:
-		if(ver.wServicePackMajor <= lpVersionInfo->wServicePackMajor)
-		    res = FALSE;
-		break;
-	    case VER_GREATER_EQUAL:
-		if(ver.wServicePackMajor < lpVersionInfo->wServicePackMajor)
-		    res = FALSE;
-		break;
-	    case VER_LESS:
-		if(ver.wServicePackMajor >= lpVersionInfo->wServicePackMajor)
-		    res = FALSE;
-		break;
-	    case VER_LESS_EQUAL:
-		if(ver.wServicePackMajor > lpVersionInfo->wServicePackMajor)
-		    res = FALSE;
-		break;
-	    default:
-	        res = FALSE;
-		SetLastError(ERROR_BAD_ARGUMENTS);
-		error_set = TRUE;
-	}
-    if(dwTypeMask & VER_SERVICEPACKMINOR && res)
-	switch(dwlConditionMask >> 4*3 & 0x07) {
-	    case VER_EQUAL:
-		if(ver.wServicePackMinor != lpVersionInfo->wServicePackMinor)
-		    res = FALSE;
-		break;
-	    case VER_GREATER:
-		if(ver.wServicePackMinor <= lpVersionInfo->wServicePackMinor)
-		    res = FALSE;
-		break;
-	    case VER_GREATER_EQUAL:
-		if(ver.wServicePackMinor < lpVersionInfo->wServicePackMinor)
-		    res = FALSE;
-		break;
-	    case VER_LESS:
-		if(ver.wServicePackMinor >= lpVersionInfo->wServicePackMinor)
-		    res = FALSE;
-		break;
-	    case VER_LESS_EQUAL:
-		if(ver.wServicePackMinor > lpVersionInfo->wServicePackMinor)
-		    res = FALSE;
-		break;
-	    default:
-	        res = FALSE;
-		SetLastError(ERROR_BAD_ARGUMENTS);
-		error_set = TRUE;
-	}
-
-    if(!(res || error_set))
-	SetLastError(ERROR_OLD_WIN_VERSION);
-    return res;
-}
-
-
-/***********************************************************************
- *	    GetWinFlags   (KERNEL.132)
- */
-DWORD WINAPI GetWinFlags16(void)
-{
-  static const long cpuflags[5] =
-    { WF_CPU086, WF_CPU186, WF_CPU286, WF_CPU386, WF_CPU486 };
-  SYSTEM_INFO si;
-  OSVERSIONINFOA ovi;
-  DWORD result;
-
-  GetSystemInfo(&si);
-
-  /* There doesn't seem to be any Pentium flag.  */
-  result = cpuflags[min(si.wProcessorLevel, 4)] | WF_ENHANCED | WF_PMODE | WF_80x87 | WF_PAGING;
-  if (si.wProcessorLevel >= 4) result |= WF_HASCPUID;
-  ovi.dwOSVersionInfoSize = sizeof(ovi);
-  GetVersionExA(&ovi);
-  if (ovi.dwPlatformId == VER_PLATFORM_WIN32_NT)
-      result |= WF_WIN32WOW; /* undocumented WF_WINNT */
-  return result;
-}
-
-
-#if 0
-/* Not used at this time. This is here for documentation only */
-
-/* WINDEBUGINFO flags values */
-#define WDI_OPTIONS         0x0001
-#define WDI_FILTER          0x0002
-#define WDI_ALLOCBREAK      0x0004
-
-/* dwOptions values */
-#define DBO_CHECKHEAP       0x0001
-#define DBO_BUFFERFILL      0x0004
-#define DBO_DISABLEGPTRAPPING 0x0010
-#define DBO_CHECKFREE       0x0020
-
-#define DBO_SILENT          0x8000
-
-#define DBO_TRACEBREAK      0x2000
-#define DBO_WARNINGBREAK    0x1000
-#define DBO_NOERRORBREAK    0x0800
-#define DBO_NOFATALBREAK    0x0400
-#define DBO_INT3BREAK       0x0100
-
-/* DebugOutput flags values */
-#define DBF_TRACE           0x0000
-#define DBF_WARNING         0x4000
-#define DBF_ERROR           0x8000
-#define DBF_FATAL           0xc000
-
-/* dwFilter values */
-#define DBF_KERNEL          0x1000
-#define DBF_KRN_MEMMAN      0x0001
-#define DBF_KRN_LOADMODULE  0x0002
-#define DBF_KRN_SEGMENTLOAD 0x0004
-#define DBF_USER            0x0800
-#define DBF_GDI             0x0400
-#define DBF_MMSYSTEM        0x0040
-#define DBF_PENWIN          0x0020
-#define DBF_APPLICATION     0x0008
-#define DBF_DRIVER          0x0010
-
-#endif /* NOLOGERROR */
-
-
-/***********************************************************************
- *	    GetWinDebugInfo   (KERNEL.355)
- */
-BOOL16 WINAPI GetWinDebugInfo16(WINDEBUGINFO16 *lpwdi, UINT16 flags)
-{
-    FIXME("(%8lx,%d): stub returning 0\n",
-	  (unsigned long)lpwdi, flags);
-    /* 0 means not in debugging mode/version */
-    /* Can this type of debugging be used in wine ? */
-    /* Constants: WDI_OPTIONS WDI_FILTER WDI_ALLOCBREAK */
-    return 0;
-}
-
-
-/***********************************************************************
- *	    SetWinDebugInfo   (KERNEL.356)
- */
-BOOL16 WINAPI SetWinDebugInfo16(WINDEBUGINFO16 *lpwdi)
-{
-    FIXME("(%8lx): stub returning 0\n", (unsigned long)lpwdi);
-    /* 0 means not in debugging mode/version */
-    /* Can this type of debugging be used in wine ? */
-    /* Constants: WDI_OPTIONS WDI_FILTER WDI_ALLOCBREAK */
-    return 0;
-}
-
-
-/***********************************************************************
- *           K329                    (KERNEL.329)
- *
- * TODO:
- * Should fill lpBuffer only if DBO_BUFFERFILL has been set by SetWinDebugInfo()
- */
-void WINAPI DebugFillBuffer(LPSTR lpBuffer, WORD wBytes)
-{
-	memset(lpBuffer, DBGFILL_BUFFER, wBytes);
-}
-
-/***********************************************************************
- *           DiagQuery                          (KERNEL.339)
- *
- * returns TRUE if Win called with "/b" (bootlog.txt)
- */
-BOOL16 WINAPI DiagQuery16(void)
-{
-	/* perhaps implement a Wine "/b" command line flag sometime ? */
-	return FALSE;
-}
-
-/***********************************************************************
- *           DiagOutput                         (KERNEL.340)
- *
- * writes a debug string into <windir>\bootlog.txt
- */
-void WINAPI DiagOutput16(LPCSTR str)
-{
-        /* FIXME */
-	DPRINTF("DIAGOUTPUT:%s\n", debugstr_a(str));
-}
diff --git a/win32/newfns.c b/win32/newfns.c
index 54559c120653e3273d7922efbfebdecb1c07c666..51ae2ea89d6de3e1681afa15d72d4de2c2d3d81b 100644
--- a/win32/newfns.c
+++ b/win32/newfns.c
@@ -45,17 +45,6 @@ at a later date. */
 WINE_DEFAULT_DEBUG_CHANNEL(win32);
 
 
-/****************************************************************************
- *		FlushInstructionCache (KERNEL32.@)
- */
-BOOL WINAPI FlushInstructionCache(HANDLE hProcess, LPCVOID lpBaseAddress, SIZE_T dwSize)
-{
-    if (GetVersion() & 0x80000000) return TRUE; /* not NT, always TRUE */
-    FIXME("(%p,%p,0x%08lx): stub\n",hProcess, lpBaseAddress, dwSize);
-    return TRUE;
-}
-
-
 /******************************************************************************
  * GetCompressedFileSizeA [KERNEL32.@]
  *