Skip to content

Commit

Permalink
[WINVER] Display compatibility information
Browse files Browse the repository at this point in the history
Also don't hardcode the OS name.
  • Loading branch information
TAN-Gaming committed Jan 24, 2025
1 parent 205eadc commit 679047b
Show file tree
Hide file tree
Showing 7 changed files with 263 additions and 9 deletions.
10 changes: 8 additions & 2 deletions base/applications/winver/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@

add_executable(winver winver.c winver.rc)
list(APPEND SOURCE
osinfo.c
winver.c
winver_p.h)

add_executable(winver ${SOURCE} winver.rc)
set_module_type(winver win32gui UNICODE)
add_importlibs(winver shell32 comctl32 msvcrt kernel32)
add_importlibs(winver advapi32 user32 shell32 comctl32 msvcrt kernel32)
add_pch(winver winver_p.h SOURCE)
add_cd_file(TARGET winver DESTINATION reactos/system32 FOR all)
7 changes: 7 additions & 0 deletions base/applications/winver/lang/en-US.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US

STRINGTABLE
BEGIN
IDS_OSINFO_COMPAT_FORMAT "Reporting NT %lu.%lu (Build %lu%s)"
IDS_OSINFO_SPK_FORMAT ": %s"
END
183 changes: 183 additions & 0 deletions base/applications/winver/osinfo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
/*
* PROJECT: ReactOS Version Program
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
* PURPOSE: Retrieve OS name and simple compatibility information
* COPYRIGHT: Copyright 2025 Thamatip Chitpong <[email protected]>
*/

#include "winver_p.h"

#define OSINFO_KEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"
#define MAJOR_VER_MAX_LEN 16
#define MINOR_VER_MAX_LEN 16
#define BUILD_NUMBER_MAX_LEN 16

static
LPWSTR
Winver_GetRegValueString(
_In_ HKEY hKey,
_In_ LPCWSTR lpValue)
{
DWORD dwType = REG_NONE;
DWORD dwSize;
LONG lError;
LPWSTR pszValue;

lError = RegQueryValueExW(hKey, lpValue, NULL, &dwType, NULL, &dwSize);
if (lError != ERROR_SUCCESS || dwType != REG_SZ)
return NULL;

/* NOTE: Reserved space for a NULL terminator */
pszValue = HeapAlloc(GetProcessHeap(), 0, dwSize + sizeof(WCHAR));
if (!pszValue)
return NULL;

lError = RegQueryValueExW(hKey, lpValue, NULL, &dwType, (LPBYTE)pszValue, &dwSize);
if (lError != ERROR_SUCCESS)
{
HeapFree(GetProcessHeap(), 0, pszValue);
return NULL;
}

/* Ensure the returned string is NULL terminated */
pszValue[dwSize / sizeof(WCHAR)] = UNICODE_NULL;

return pszValue;
}

static
LPWSTR
Winver_GetOSProductName(VOID)
{
HKEY hKey;
LONG lError;
LPWSTR pszRet;

lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
OSINFO_KEY,
0,
KEY_QUERY_VALUE,
&hKey);
if (lError != ERROR_SUCCESS)
return NULL;

pszRet = Winver_GetRegValueString(hKey, L"ProductName");

RegCloseKey(hKey);

return pszRet;
}

static
VOID
Winver_FormatCompatSpkInfo(
_Inout_ PWINVER_OS_INFO OSInfo,
_In_ LPCWSTR lpSpk)
{
static const WCHAR szFmtSpecs[] = L"%s";
WCHAR szFormat[8];
DWORD dwLength;

dwLength = LoadStringW(GetModuleHandleW(NULL),
IDS_OSINFO_SPK_FORMAT,
szFormat,
_countof(szFormat));
if (dwLength < CONST_STR_LEN(szFmtSpecs))
{
return;
}
dwLength -= CONST_STR_LEN(szFmtSpecs);

/* NOTE: dwLength excludes format specifiers and includes a NULL terminator */
dwLength += wcslen(lpSpk) + 1;
OSInfo->pszCompatSpk = HeapAlloc(GetProcessHeap(), 0, dwLength * sizeof(WCHAR));
if (OSInfo->pszCompatSpk)
{
StringCchPrintfW(OSInfo->pszCompatSpk, dwLength, szFormat, lpSpk);
}
}

static
VOID
Winver_FormatCompatInfo(
_Inout_ PWINVER_OS_INFO OSInfo)
{
static const WCHAR szFmtSpecs[] = L"%lu%lu%lu%s";
WCHAR szFormat[64];
DWORD dwLength;
OSVERSIONINFOEXW VerInfo;

dwLength = LoadStringW(GetModuleHandleW(NULL),
IDS_OSINFO_COMPAT_FORMAT,
szFormat,
_countof(szFormat));
if (dwLength < CONST_STR_LEN(szFmtSpecs))
{
return;
}
dwLength -= CONST_STR_LEN(szFmtSpecs);

VerInfo.dwOSVersionInfoSize = sizeof(VerInfo);
if (!GetVersionExW(&VerInfo))
return;

/* Service pack info is optional */
if (*VerInfo.szCSDVersion)
{
Winver_FormatCompatSpkInfo(OSInfo, VerInfo.szCSDVersion);
if (OSInfo->pszCompatSpk)
{
dwLength += wcslen(OSInfo->pszCompatSpk);
}
}

/* NOTE: dwLength excludes format specifiers and includes a NULL terminator */
dwLength += MAJOR_VER_MAX_LEN + MINOR_VER_MAX_LEN + BUILD_NUMBER_MAX_LEN + 1;
OSInfo->pszCompatInfo = HeapAlloc(GetProcessHeap(), 0, dwLength * sizeof(WCHAR));
if (OSInfo->pszCompatInfo)
{
StringCchPrintfW(OSInfo->pszCompatInfo, dwLength, szFormat,
VerInfo.dwMajorVersion,
VerInfo.dwMinorVersion,
VerInfo.dwBuildNumber,
OSInfo->pszCompatSpk ? OSInfo->pszCompatSpk : L"");
}
}

PWINVER_OS_INFO
Winver_GetOSInfo(VOID)
{
PWINVER_OS_INFO OSInfo;

OSInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*OSInfo));
if (!OSInfo)
return NULL;

/* OS name */
OSInfo->pszName = Winver_GetOSProductName();
if (!OSInfo->pszName)
{
/* This info must be valid */
HeapFree(GetProcessHeap(), 0, OSInfo);
return NULL;
}

/* Simple compatibility information */
Winver_FormatCompatInfo(OSInfo);

return OSInfo;
}

VOID
Winver_FreeOSInfo(
_In_ PWINVER_OS_INFO OSInfo)
{
if (OSInfo)
{
HeapFree(GetProcessHeap(), 0, OSInfo->pszCompatInfo);
HeapFree(GetProcessHeap(), 0, OSInfo->pszCompatSpk);
HeapFree(GetProcessHeap(), 0, OSInfo->pszName);

HeapFree(GetProcessHeap(), 0, OSInfo);
}
}
4 changes: 4 additions & 0 deletions base/applications/winver/resource.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#pragma once

#define IDS_OSINFO_COMPAT_FORMAT 1
#define IDS_OSINFO_SPK_FORMAT 2
21 changes: 14 additions & 7 deletions base/applications/winver/winver.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,13 @@
* FILE: base/applications/winver/winver.c
*/

#include <stdarg.h>
#include <windef.h>
#include <winbase.h>
#include <winuser.h>
#include <commctrl.h>
#include <shellapi.h>
#include "winver_p.h"

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
INITCOMMONCONTROLSEX iccx;
PWINVER_OS_INFO OSInfo;
int Ret;

UNREFERENCED_PARAMETER(hInstance);
UNREFERENCED_PARAMETER(hPrevInstance);
Expand All @@ -25,5 +22,15 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi
iccx.dwICC = ICC_STANDARD_CLASSES | ICC_WIN95_CLASSES;
InitCommonControlsEx(&iccx);

return ShellAboutW(NULL, L"ReactOS", NULL, NULL);
OSInfo = Winver_GetOSInfo();

/* NOTE: Display the default contents if OSInfo is not available */
Ret = ShellAboutW(NULL,
OSInfo ? OSInfo->pszName : L"ReactOS",
OSInfo ? OSInfo->pszCompatInfo : NULL,
NULL);

Winver_FreeOSInfo(OSInfo);

return Ret;
}
9 changes: 9 additions & 0 deletions base/applications/winver/winver.rc
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,18 @@
#include <windef.h>
#include <winuser.h>

#include "resource.h"

#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Version Program"
#define REACTOS_STR_INTERNAL_NAME "winver"
#define REACTOS_STR_ORIGINAL_FILENAME "winver.exe"
#include <reactos/version.rc>

#include <reactos/manifest_exe.rc>

/* UTF-8 */
#pragma code_page(65001)

#ifdef LANGUAGE_EN_US
#include "lang/en-US.rc"
#endif
38 changes: 38 additions & 0 deletions base/applications/winver/winver_p.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* PROJECT: ReactOS Version Program
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
* PURPOSE: Main header
* COPYRIGHT: Copyright 2025 Thamatip Chitpong <[email protected]>
*/

#pragma once

#include <stdarg.h>
#include <stdlib.h>

#include <windef.h>
#include <winbase.h>
#include <winreg.h>
#include <winuser.h>
#include <commctrl.h>
#include <shellapi.h>

#include <strsafe.h>

#include "resource.h"

#define CONST_STR_LEN(str) (_countof(str) - 1)

typedef struct _WINVER_OS_INFO
{
LPWSTR pszName;
LPWSTR pszCompatSpk;
LPWSTR pszCompatInfo;
} WINVER_OS_INFO, *PWINVER_OS_INFO;

PWINVER_OS_INFO
Winver_GetOSInfo(VOID);

VOID
Winver_FreeOSInfo(
_In_ PWINVER_OS_INFO OSInfo);

0 comments on commit 679047b

Please sign in to comment.