241 lines
8.1 KiB
C
241 lines
8.1 KiB
C
/*
|
|
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#include "config.h"
|
|
#include "wine/port.h"
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include "ntstatus.h"
|
|
#define WIN32_NO_STATUS
|
|
#include "windef.h"
|
|
#include "winbase.h"
|
|
#include "wingdi.h"
|
|
#include "winuser.h"
|
|
#include "winternl.h"
|
|
#include "winerror.h"
|
|
#include "wine/unicode.h"
|
|
#include "wine/debug.h"
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(ver);
|
|
|
|
|
|
static inline UCHAR version_update_condition(UCHAR *last_condition, UCHAR condition)
|
|
{
|
|
switch (*last_condition)
|
|
{
|
|
case 0:
|
|
*last_condition = condition;
|
|
break;
|
|
case VER_EQUAL:
|
|
if (condition >= VER_EQUAL && condition <= VER_LESS_EQUAL)
|
|
{
|
|
*last_condition = condition;
|
|
return condition;
|
|
}
|
|
break;
|
|
case VER_GREATER:
|
|
case VER_GREATER_EQUAL:
|
|
if (condition >= VER_EQUAL && condition <= VER_GREATER_EQUAL)
|
|
return condition;
|
|
break;
|
|
case VER_LESS:
|
|
case VER_LESS_EQUAL:
|
|
if (condition == VER_EQUAL || (condition >= VER_LESS && condition <= VER_LESS_EQUAL))
|
|
return condition;
|
|
break;
|
|
}
|
|
if (!condition) *last_condition |= 0x10;
|
|
return *last_condition & 0xf;
|
|
}
|
|
|
|
static inline BOOL version_compare_values(ULONG left, ULONG right, UCHAR condition)
|
|
{
|
|
switch (condition)
|
|
{
|
|
case VER_EQUAL:
|
|
if (left != right) return FALSE;
|
|
break;
|
|
case VER_GREATER:
|
|
if (left <= right) return FALSE;
|
|
break;
|
|
case VER_GREATER_EQUAL:
|
|
if (left < right) return FALSE;
|
|
break;
|
|
case VER_LESS:
|
|
if (left >= right) return FALSE;
|
|
break;
|
|
case VER_LESS_EQUAL:
|
|
if (left > right) return FALSE;
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
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 info, DWORD dwTypeMask,
|
|
DWORDLONG dwlConditionMask)
|
|
{
|
|
OSVERSIONINFOEXW ver;
|
|
|
|
TRACE("(%p 0x%x 0x%s)\n", info, dwTypeMask, wine_dbgstr_longlong(dwlConditionMask));
|
|
|
|
ver.dwOSVersionInfoSize = sizeof(ver);
|
|
if (!GetVersionExW((OSVERSIONINFOW*)&ver)) return FALSE;
|
|
|
|
if (!dwTypeMask || !dwlConditionMask)
|
|
{
|
|
SetLastError(ERROR_BAD_ARGUMENTS);
|
|
return FALSE;
|
|
}
|
|
|
|
if (dwTypeMask & VER_PRODUCT_TYPE)
|
|
{
|
|
if (!version_compare_values(ver.wProductType, info->wProductType, dwlConditionMask >> 7*3 & 0x07))
|
|
goto mismatch;
|
|
}
|
|
if (dwTypeMask & VER_SUITENAME)
|
|
switch (dwlConditionMask >> 6*3 & 0x07)
|
|
{
|
|
case VER_AND:
|
|
if ((info->wSuiteMask & ver.wSuiteMask) != info->wSuiteMask)
|
|
goto mismatch;
|
|
break;
|
|
case VER_OR:
|
|
if (!(info->wSuiteMask & ver.wSuiteMask) && info->wSuiteMask)
|
|
goto mismatch;
|
|
break;
|
|
default:
|
|
SetLastError(ERROR_BAD_ARGUMENTS);
|
|
return FALSE;
|
|
}
|
|
if (dwTypeMask & VER_PLATFORMID)
|
|
{
|
|
if (!version_compare_values(ver.dwPlatformId, info->dwPlatformId, dwlConditionMask >> 3*3 & 0x07))
|
|
goto mismatch;
|
|
}
|
|
if (dwTypeMask & VER_BUILDNUMBER)
|
|
{
|
|
if (!version_compare_values(ver.dwBuildNumber, info->dwBuildNumber, dwlConditionMask >> 2*3 & 0x07))
|
|
goto mismatch;
|
|
}
|
|
|
|
if (dwTypeMask & (VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR))
|
|
{
|
|
unsigned char condition, last_condition = 0;
|
|
BOOL succeeded = TRUE, do_next_check = TRUE;
|
|
|
|
if (dwTypeMask & VER_MAJORVERSION)
|
|
{
|
|
condition = version_update_condition(&last_condition, dwlConditionMask >> 1*3 & 0x07);
|
|
succeeded = version_compare_values(ver.dwMajorVersion, info->dwMajorVersion, condition);
|
|
do_next_check = (ver.dwMajorVersion == info->dwMajorVersion) &&
|
|
((condition >= VER_EQUAL) && (condition <= VER_LESS_EQUAL));
|
|
}
|
|
if ((dwTypeMask & VER_MINORVERSION) && do_next_check)
|
|
{
|
|
condition = version_update_condition(&last_condition, dwlConditionMask >> 0*3 & 0x07);
|
|
succeeded = version_compare_values(ver.dwMinorVersion, info->dwMinorVersion, condition);
|
|
do_next_check = (ver.dwMinorVersion == info->dwMinorVersion) &&
|
|
((condition >= VER_EQUAL) && (condition <= VER_LESS_EQUAL));
|
|
}
|
|
if ((dwTypeMask & VER_SERVICEPACKMAJOR) && do_next_check)
|
|
{
|
|
condition = version_update_condition(&last_condition, dwlConditionMask >> 5*3 & 0x07);
|
|
succeeded = version_compare_values(ver.wServicePackMajor, info->wServicePackMajor, condition);
|
|
do_next_check = (ver.wServicePackMajor == info->wServicePackMajor) &&
|
|
((condition >= VER_EQUAL) && (condition <= VER_LESS_EQUAL));
|
|
}
|
|
if ((dwTypeMask & VER_SERVICEPACKMINOR) && do_next_check)
|
|
{
|
|
condition = version_update_condition(&last_condition, dwlConditionMask >> 4*3 & 0x07);
|
|
succeeded = version_compare_values(ver.wServicePackMinor, info->wServicePackMinor, condition);
|
|
}
|
|
|
|
if (!succeeded) goto mismatch;
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
mismatch:
|
|
SetLastError(ERROR_OLD_WIN_VERSION);
|
|
return FALSE;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* TermsrvAppInstallMode (KERNEL32.@)
|
|
*
|
|
* Find out whether the terminal server is in INSTALL or EXECUTE mode.
|
|
*/
|
|
BOOL WINAPI TermsrvAppInstallMode(void)
|
|
{
|
|
FIXME("stub\n");
|
|
return FALSE;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* SetTermsrvAppInstallMode (KERNEL32.@)
|
|
*
|
|
* This function is said to switch between the INSTALL (TRUE) or
|
|
* EXECUTE (FALSE) terminal server modes.
|
|
*
|
|
* This function always returns zero on WinXP Home so it's probably
|
|
* safe to return that value in most cases. However, if a terminal
|
|
* server is running it will probably return something else.
|
|
*/
|
|
DWORD WINAPI SetTermsrvAppInstallMode(BOOL bInstallMode)
|
|
{
|
|
FIXME("(%d): stub\n", bInstallMode);
|
|
return 0;
|
|
}
|