Skip to content

Commit

Permalink
[WINVER] Display OS information
Browse files Browse the repository at this point in the history
  • Loading branch information
TAN-Gaming committed Jan 6, 2025
1 parent 205eadc commit 5e0c6a8
Show file tree
Hide file tree
Showing 8 changed files with 416 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_exe.h)

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

STRINGTABLE
BEGIN
IDS_OSINFO_BUILD_FORMAT "Build: %s"
IDS_OSINFO_COMPAT_FORMAT "Compatibility: Windows NT %s (Build %s%s)"
IDS_OSINFO_INSTALL_FORMAT "Install location: %s"
IDS_OSINFO_SPK_SEPARATOR ": "
END
9 changes: 9 additions & 0 deletions base/applications/winver/lang/th-TH.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
LANGUAGE LANG_THAI, SUBLANG_DEFAULT

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

#include "winver_exe.h"

#define WINVER_OSINFO_KEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"

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, 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_FormatBuildInfo(
_In_ PWINVER_OS_INFO OSInfo)
{
static const WCHAR szFmtSpecs[] = L"%s";
WCHAR szFormat[64];
DWORD dwLength;
LPWSTR pszInfo;

/* Required info must be valid */
if (!OSInfo->pszBuild)
return NULL;

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

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

return pszInfo;
}

static
LPWSTR
Winver_FormatCompatSpkInfo(
_In_ PWINVER_OS_INFO OSInfo)
{
WCHAR szSpkSep[4];
DWORD dwLength;
LPWSTR pszInfo;

/* Required info must be valid */
if (!OSInfo->pszCompatSpk)
return NULL;

dwLength = LoadStringW(GetModuleHandleW(NULL),
IDS_OSINFO_SPK_SEPARATOR,
szSpkSep,
_countof(szSpkSep));
if (dwLength == 0)
return NULL;

/* NOTE: dwLength includes a NULL terminator */
dwLength += wcslen(OSInfo->pszCompatSpk) + 1;
pszInfo = HeapAlloc(GetProcessHeap(), 0, dwLength * sizeof(WCHAR));
if (pszInfo)
{
StringCchPrintfW(pszInfo, dwLength, L"%s%s", szSpkSep, OSInfo->pszCompatSpk);
}

return pszInfo;
}

static
LPWSTR
Winver_FormatCompatInfo(
_In_ PWINVER_OS_INFO OSInfo)
{
static const WCHAR szFmtSpecs[] = L"%s%s%s";
WCHAR szFormat[64];
DWORD dwLength;
LPWSTR pszSpk;
LPWSTR pszInfo;

/* Required info must be valid */
if (!OSInfo->pszCompatVer || !OSInfo->pszCompatBuild)
return NULL;

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

/* Service pack info is optional */
pszSpk = Winver_FormatCompatSpkInfo(OSInfo);
if (pszSpk)
{
dwLength += wcslen(pszSpk);
}

/* NOTE: dwLength excludes format specifiers and includes a NULL terminator */
dwLength += wcslen(OSInfo->pszCompatVer) + wcslen(OSInfo->pszCompatBuild) + 1;
pszInfo = HeapAlloc(GetProcessHeap(), 0, dwLength * sizeof(WCHAR));
if (pszInfo)
{
StringCchPrintfW(pszInfo, dwLength, szFormat,
OSInfo->pszCompatVer,
OSInfo->pszCompatBuild,
pszSpk ? pszSpk : L"");
}

HeapFree(GetProcessHeap(), 0, pszSpk);
return pszInfo;
}

static
LPWSTR
Winver_FormatInstallInfo(
_In_ PWINVER_OS_INFO OSInfo)
{
static const WCHAR szFmtSpecs[] = L"%s";
WCHAR szFormat[64];
DWORD dwLength;
LPWSTR pszInfo;

/* Required info must be valid */
if (!OSInfo->pszSystemRoot)
return NULL;

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

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

return pszInfo;
}

static
VOID
Winver_FormatOSInfo(
_Inout_ PWINVER_OS_INFO OSInfo)
{
static const WCHAR szFormat[] = L"%s\n%s\n%s";
static const WCHAR szFmtSpecs[] = L"%s%s%s";
LPWSTR pszBuildInfo;
LPWSTR pszCompatInfo = NULL;
LPWSTR pszInstallInfo = NULL;
LPWSTR pszInfo = NULL;
DWORD dwLength;

dwLength = CONST_STR_LEN(szFormat) - CONST_STR_LEN(szFmtSpecs);

/* OS build info (line 1) */
pszBuildInfo = Winver_FormatBuildInfo(OSInfo);
if (!pszBuildInfo)
{
return;
}
dwLength += wcslen(pszBuildInfo);

/* OS compatibility info (line 2) */
pszCompatInfo = Winver_FormatCompatInfo(OSInfo);
if (!pszCompatInfo)
{
goto Cleanup;
}
dwLength += wcslen(pszCompatInfo);

/* OS installation info (line 3) */
pszInstallInfo = Winver_FormatInstallInfo(OSInfo);
if (!pszInstallInfo)
{
goto Cleanup;
}
dwLength += wcslen(pszInstallInfo);

/* NOTE: dwLength excludes format specifiers and includes a NULL terminator */
dwLength += 1;
pszInfo = HeapAlloc(GetProcessHeap(), 0, dwLength * sizeof(WCHAR));
if (pszInfo)
{
StringCchPrintfW(pszInfo, dwLength, szFormat,
pszBuildInfo,
pszCompatInfo,
pszInstallInfo);

OSInfo->pszFormatted = pszInfo;
}

Cleanup:
HeapFree(GetProcessHeap(), 0, pszInstallInfo);
HeapFree(GetProcessHeap(), 0, pszCompatInfo);
HeapFree(GetProcessHeap(), 0, pszBuildInfo);
}

PWINVER_OS_INFO
Winver_GetOSInfo(VOID)
{
HKEY hKey;
LONG lError;
PWINVER_OS_INFO OSInfo;

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

lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
WINVER_OSINFO_KEY,
0,
KEY_QUERY_VALUE,
&hKey);
if (lError != ERROR_SUCCESS)
{
HeapFree(GetProcessHeap(), 0, OSInfo);
return NULL;
}

/* OS name */
OSInfo->pszProductName = Winver_GetRegValueString(hKey, L"ProductName");
if (!OSInfo->pszProductName)
{
/* ShellAboutW: This info must be valid */
RegCloseKey(hKey);
HeapFree(GetProcessHeap(), 0, OSInfo);
return NULL;
}

/* OS build number */
OSInfo->pszBuild = Winver_GetRegValueString(hKey, L"BuildLab");

/* Compatible NT version */
OSInfo->pszCompatVer = Winver_GetRegValueString(hKey, L"CurrentVersion");

/* Compatible NT build number */
OSInfo->pszCompatBuild = Winver_GetRegValueString(hKey, L"CurrentBuildNumber");

/* Compatible NT service pack (optional) */
OSInfo->pszCompatSpk = Winver_GetRegValueString(hKey, L"CSDVersion");

/* OS install directory */
OSInfo->pszSystemRoot = Winver_GetRegValueString(hKey, L"SystemRoot");

RegCloseKey(hKey);

Winver_FormatOSInfo(OSInfo);

return OSInfo;
}

VOID
Winver_FreeOSInfo(
_In_ PWINVER_OS_INFO OSInfo)
{
if (OSInfo)
{
HeapFree(GetProcessHeap(), 0, OSInfo->pszFormatted);
HeapFree(GetProcessHeap(), 0, OSInfo->pszSystemRoot);
HeapFree(GetProcessHeap(), 0, OSInfo->pszCompatSpk);
HeapFree(GetProcessHeap(), 0, OSInfo->pszCompatBuild);
HeapFree(GetProcessHeap(), 0, OSInfo->pszCompatVer);
HeapFree(GetProcessHeap(), 0, OSInfo->pszBuild);
HeapFree(GetProcessHeap(), 0, OSInfo->pszProductName);

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

#define IDS_OSINFO_BUILD_FORMAT 1
#define IDS_OSINFO_COMPAT_FORMAT 2
#define IDS_OSINFO_INSTALL_FORMAT 3
#define IDS_OSINFO_SPK_SEPARATOR 4
20 changes: 13 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_exe.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,14 @@ 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();

Ret = ShellAboutW(NULL,
OSInfo ? OSInfo->pszProductName : L"ReactOS",
OSInfo ? OSInfo->pszFormatted : NULL,
NULL);

Winver_FreeOSInfo(OSInfo);

return Ret;
}
Loading

0 comments on commit 5e0c6a8

Please sign in to comment.