From 240b0a9b482282064b7d2e9d7dea67df622774da Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 24 Sep 2003 05:26:00 +0000 Subject: [PATCH] Moved the Windows version code to dlls/ntdll, and implemented RtlGetVersion and RtlVerifyVersionInfo. Moved the 16-bit and DOS version support to dlls/kernel. --- dlls/kernel/Makefile.in | 1 + dlls/kernel/process.c | 14 +- dlls/kernel/version.c | 459 +++++++++++++++++++ dlls/ntdll/Makefile.in | 2 +- dlls/ntdll/rtl.c | 43 -- dlls/ntdll/version.c | 733 ++++++++++++++++++++++++++++++ files/drive.c | 12 +- include/winbase.h | 104 +---- include/windef.h | 3 +- include/wine/winbase16.h | 2 +- include/winnt.h | 94 ++++ include/winternl.h | 2 + misc/version.c | 1102 ---------------------------------------------- win32/newfns.c | 11 - 14 files changed, 1314 insertions(+), 1268 deletions(-) create mode 100644 dlls/kernel/version.c create mode 100644 dlls/ntdll/version.c delete mode 100644 misc/version.c diff --git a/dlls/kernel/Makefile.in b/dlls/kernel/Makefile.in index 3ad890951ae..d3cc40cffe2 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 272e7910407..09bc9d164e2 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 00000000000..053eaeedd25 --- /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 +#include +#include +#include +#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 \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 25f4277bf38..607ee97ae76 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 545616fa678..bc8cd7a55e2 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 00000000000..880ae318413 --- /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 +#include +#include +#include +#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 acbc93de093..6fb0e5c96e0 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 eeb3de46fdf..a617d933373 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 765f451615e..809fdd3f925 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 - /* 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 /* Polymorphic types */ diff --git a/include/wine/winbase16.h b/include/wine/winbase16.h index 3b889be7de5..6ec65ce7262 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 6dba3e2510a..7915d0bf27f 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 ecd0964c354..8592ee98f33 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 39a07f605f1..00000000000 --- 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 -#include -#include -#include -#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 \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 54559c12065..51ae2ea89d6 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.@] * -- 2.11.4.GIT