hiyohiyo / CrystalDiskInfo

CrystalDiskInfo
https://github.com/hiyohiyo/CrystalDiskInfo
MIT License
1.59k stars 177 forks source link

About IsWindowsVersionOrGreaterFx #204

Open zyyujq opened 1 year ago

zyyujq commented 1 year ago

Introduction to Microsoft's official website: https://learn.microsoft.com/zh-cn/windows/win32/api/versionhelpers/nf-versionhelpers-iswindowsversionorgreater

IsWindows10OrGreater function IsWindows7OrGreater function IsWindows7SP1 OrGreater function IsWindows8OrGreater function IsWindows8Point1OrGreater function IsWindowsServer function IsWindowsVersionOrGreater function IsWindowsVistaOrGreater function IsWindowsVistaSP1OrGreater function IsWindowsVistaSP2OrGreater function IsWindowsXPOrGreater function IsWindowsXPSP1OrGreater function IsWindowsXPSP2OrGreater function IsWindowsXPSP3OrGreater function


Can you use these functions to identify the operating system?

zyyujq commented 1 year ago

In AtaSmart. cpp, CAtaSmart:: CAtaSmart()

Windows 10 and above IsWindowsVersionOrGreaterFx cannot return TRUE

The reason is that the following code in OsInfoFx.cpp cannot return TRUE: VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;

hiyohiyo commented 1 year ago

Thank you for report.

But, IsWindowsVersionOrGreaterFx(10,0) returns TRUE on my Windows 11 environment. It may work fine.

zyyujq commented 1 year ago

Mr. hiyohiyo:

IsWindowsVersionOrGreaterFx (10,0) , on the exe execution file, there is an additional manifest file manifest:


< compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> < application> < !-- Windows Vista --> < supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> < !-- Windows 7 --> < supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> < !-- Windows 8 --> < supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> < !-- Windows 8.1 --> < supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> < !-- Windows 10 --> < supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> < /application> < /compatibility>


So you can return TRUE on Windows 10 and 11.

If there is no manifest file, the exe execution file has an error on Windows 11.

if you build the CrystalDiskInfo.DLL file, even if the manifest file is attached, the shell program runs on Windows 11 and calls CrystalDiskInfo.DLL. Unfortunately, the program error.


I solved this problem temporarily with a simple method, even without the manifest file of the program.

In OsInfoFx.cpp:

#include "pch.h"
#include "stdafx.h"
#include "OsInfoFx.h"
#include "UtilityFx.h"

typedef BOOL (WINAPI* FuncGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD);
typedef BOOL (WINAPI* FuncGetNativeSystemInfo)(LPSYSTEM_INFO);
typedef BOOL (WINAPI* FuncIsWow64Process)(HANDLE hProcess,PBOOL Wow64Process);
typedef LONG (WINAPI* FuncRtlGetVersion)(POSVERSIONINFOEXW osvi);

typedef LONG NTSTATUS, * PNTSTATUS;
#define STATUS_SUCCESS (0x00000000)`

typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);

RTL_OSVERSIONINFOW GetRealOSVersion() {
    HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll");
    if (hMod) {
        RtlGetVersionPtr fxPtr = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion");
        if (fxPtr != nullptr) {
            RTL_OSVERSIONINFOW rovi = { 0 };
            rovi.dwOSVersionInfoSize = sizeof(rovi);
            if (STATUS_SUCCESS == fxPtr(&rovi)) {
                return rovi;
            }
        }
    }
    RTL_OSVERSIONINFOW rovi = { 0 };
    return rovi;
}
`

BOOL IsWindowsVersionOrGreaterFx(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
{
    OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 };
    DWORDLONG        const dwlConditionMask = VerSetConditionMask(
                                                                      VerSetConditionMask(
                                                                VerSetConditionMask(
                                                           0, VER_MAJORVERSION, VER_GREATER_EQUAL),
                                                            VER_MINORVERSION, VER_GREATER_EQUAL),
                                                          VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);

    osvi.dwMajorVersion = wMajorVersion;
    osvi.dwMinorVersion = wMinorVersion;
    osvi.wServicePackMajor = wServicePackMajor;

    //osvi.dwBuildNumber= GetRealOSVersion().dwBuildNumber;
    //osvi.dwOSVersionInfoSize = GetRealOSVersion().dwOSVersionInfoSize;
    //osvi.dwPlatformId = GetRealOSVersion().dwPlatformId;

    DWORD wntMajorVersion= GetRealOSVersion().dwMajorVersion;//W11=10
    DWORD wntMinorVersion = GetRealOSVersion().dwMinorVersion;//W11=0
    DWORD wntBuildNumber = GetRealOSVersion().dwBuildNumber;//W11=22621
    DWORD wntPlatformId = GetRealOSVersion().dwPlatformId;//W11=2
    DWORD wntOSVersionInfoSize = GetRealOSVersion().dwOSVersionInfoSize;//W11=276
    WCHAR *wntszCSDVersion = GetRealOSVersion().szCSDVersion;//W11=0x012fd0e4

    if ((wMajorVersion == wntMajorVersion) && (wntBuildNumber > 20000)) //Windows 11
    {
        return TRUE;
    }
    else
    {
        return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
    }
}
hiyohiyo commented 1 year ago

Thank you!

I do not consider environments without manifests. I will fix this problem in the future version.