/*
 * 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 "winreg.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','a',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',' ','4',0},
        4, 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',' ','2',0},
        2, 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 Server 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 WCHAR *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 WCHAR *p;
        WCHAR appversion[MAX_PATH+20];
        BOOL got_win_ver = FALSE;

        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 ))
        {
            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: switch (RtlImageNtHeader(hmod)->OptionalHeader.MinorOperatingSystemVersion){
                          case 0: return NT2K;
                          case 1: return WINXP;
                          case 2: return WIN2K3;
                          }
                  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;
    unsigned 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 WIN98;
    }

    switch (ophd->MajorOperatingSystemVersion)
    {
    case 5:
        switch (ophd->MinorOperatingSystemVersion)
        {
        case 0 : return NT2K;
        case 1 : return WINXP;
        case 2 : return WIN2K3;
        }
        break;
    case 4:
        switch(ophd->MinorOperatingSystemVersion)
        {
        case 90 : return WINME;
        case 10 : return WIN98;
        case 0  :
            switch(ophd->MajorImageVersion)
            {
            case 4 : return NT40;
            case 0 : return WIN95;
            }
            break;
        }
        break;
    case 1:
        if(ophd->MinorOperatingSystemVersion == 0)
           return WIN95;
        break;
    }
    FIXME("Unknown EXE OS version %d.%d, please report !!\n",
          ophd->MajorOperatingSystemVersion, ophd->MinorOperatingSystemVersion );
    return WIN98;
}

/**********************************************************************
 *         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;
}
