WINDHAWK: Classic Winver
Oct 18, 2023 12:33:09 GMT -8
Post by aubymori on Oct 18, 2023 12:33:09 GMT -8
I've made a mod for Windhawk which will restore physical memory (if your dialog is set up right, SEE THE README) and make the license link open Notepad instead of the custom dialog.
Again, SEE THE README.
Before:
After:
Mod code
// ==WindhawkMod==
// @id classic-winver
// @name Classic Winver
// @description Show physical memory in Winver
// @version 1.0.0
// @author aubymori
// @github https://github.com/aubymori
// @include *
// ==/WindhawkMod==
// ==WindhawkModReadme==
/*
# Classic Winver
Show the physical memory in Winver, like Vista and before, and optionally
make the license link open `C:\Windows\System32\eula.txt` in Notepad instead
of the default `C:\Windows\System32\license.rtf` in the custom popup.
# IMPORTANT
- For the Physical memory available to Windows string to work properly, the control for it
*MUST* have an ID of 13571.
- For the License link to work, you *MUST* have `eula.txt` in `C:\Windows\System32` and
`C:\Windows\SysWOW64`.
*/
// ==/WindhawkModReadme==
// ==WindhawkModSettings==
/*
- physmem: true
$name: Physical memory available to Windows
$description: Show the physical memory, like Windows Vista and before
- notepadeula: true
$name: Old EULA behavior
$description: Open C:\Windows\System32\eula.txt instead of C:\Windows\System32\license.rtf in a popup
- memformat: "%s KB"
$name: Memory string format
$description: String format to use for Physical memory available to Windows.
*/
// ==/WindhawkModSettings==
#include <windhawk_api.h>
#include <windhawk_utils.h>
struct {
bool physmem;
bool notepadeula;
wchar_t *memformat;
} settings;
#define IDD_CONVENTIONAL 13571
#define IDD_EULA 13586
#define BytesToK(pDW) (*(pDW) = (*(pDW) + 512) / 1024)
#define MAX_INT64_SIZE 30
#define MAX_COMMA_NUMBER_SIZE (MAX_INT64_SIZE + 10)
/**************************************************************************
// Converts 64 bit Int to Str
**************************************************************************/
void Int64ToStr( __int64 n, LPWSTR lpBuffer)
{
WCHAR szTemp[MAX_INT64_SIZE];
__int64 iChr;
iChr = 0;
do {
szTemp[iChr++] = L'0' + (WCHAR)(n % 10);
n = n / 10;
} while (n != 0);
do {
iChr--;
*lpBuffer++ = szTemp[iChr];
} while (iChr != 0);
*lpBuffer++ = '\0';
}
//
// Obtain NLS info about how numbers should be grouped.
//
// The annoying thing is that LOCALE_SGROUPING and NUMBERFORMAT
// have different ways of specifying number grouping.
//
// LOCALE NUMBERFMT Sample Country
//
// 3;0 3 1,234,567 United States
// 3;2;0 32 12,34,567 India
// 3 30 1234,567 ??
//
// Not my idea. That's the way it works.
//
// Bonus treat - Win9x doesn't support complex number formats,
// so we return only the first number.
//
UINT GetNLSGrouping(void)
{
UINT grouping;
LPWSTR psz;
WCHAR szGrouping[32];
// If no locale info, then assume Western style thousands
if (!GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SGROUPING, szGrouping, ARRAYSIZE(szGrouping)))
return 3;
grouping = 0;
psz = szGrouping;
for (;;)
{
if (*psz == L'0') break; // zero - stop
else if ((UINT)(*psz - L'0') < 10) // digit - accumulate it
grouping = grouping * 10 + (UINT)(*psz - L'0');
else if (*psz) // punctuation - ignore it
{ }
else // end of string, no "0" found
{
grouping = grouping * 10; // put zero on end (see examples)
break; // and finished
}
psz++;
}
return grouping;
}
// takes a DWORD add commas etc to it and puts the result in the buffer
STDAPI_(LPWSTR) AddCommas64(LONGLONG n, LPWSTR pszResult, UINT cchResult)
{
WCHAR szTemp[MAX_COMMA_NUMBER_SIZE];
WCHAR szSep[5];
NUMBERFMT nfmt;
nfmt.NumDigits=0;
nfmt.LeadingZero=0;
nfmt.Grouping = GetNLSGrouping();
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szSep, ARRAYSIZE(szSep));
nfmt.lpDecimalSep = nfmt.lpThousandSep = szSep;
nfmt.NegativeOrder= 0;
Int64ToStr(n, szTemp);
if (GetNumberFormat(LOCALE_USER_DEFAULT, 0, szTemp, &nfmt, pszResult, cchResult) == 0)
{
wcscpy_s(pszResult, cchResult, szTemp); // ok to truncate, for display only
}
return pszResult;
}
typedef INT_PTR (CALLBACK *AboutDlgProc_t)(HWND, UINT, WPARAM, LPARAM);
AboutDlgProc_t AboutDlgProc_orig;
INT_PTR CALLBACK AboutDlgProc_hook(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch (uMsg)
{
/* Display memory information */
case WM_INITDIALOG:
if (settings.physmem)
{
MEMORYSTATUSEX MemoryStatus;
DWORDLONG ullTotalPhys;
MemoryStatus.dwLength = sizeof(MEMORYSTATUSEX);
GlobalMemoryStatusEx(&MemoryStatus);
ullTotalPhys = MemoryStatus.ullTotalPhys;
BytesToK(&ullTotalPhys);
WCHAR szBuffer[64];
WCHAR szNumBuf1[32];
wsprintf(szBuffer, settings.memformat, AddCommas64(ullTotalPhys, szNumBuf1, ARRAYSIZE(szNumBuf1)));
SetDlgItemTextW(hWnd, IDD_CONVENTIONAL, szBuffer);
}
/* Open EULA in notepad */
case WM_NOTIFY:
if (settings.notepadeula
&& (IDD_EULA == (int)wParam)
&& (NM_CLICK == ((LPNMHDR)lParam)->code))
{
SHELLEXECUTEINFOW sei = { 0 };
sei.cbSize = sizeof(SHELLEXECUTEINFOW);
sei.fMask = SEE_MASK_DOENVSUBST;
sei.hwnd = hWnd;
sei.nShow = SW_SHOWNORMAL;
sei.lpFile = L"%windir%\\system32\\eula.txt";
ShellExecuteExW(&sei);
break;
}
default:
return AboutDlgProc_orig(
hWnd, uMsg, wParam, lParam
);
}
return TRUE;
}
void LoadSettings(void)
{
settings.physmem = Wh_GetIntSetting(L"physmem");
settings.notepadeula = Wh_GetIntSetting(L"notepadeula");
settings.memformat = (wchar_t *)Wh_GetStringSetting(L"memformat");
}
BOOL Wh_ModInit(void)
{
LoadSettings();
HMODULE hShell32 = LoadLibraryW(L"shell32.dll");
if (!hShell32)
{
Wh_Log(L"Failed to load shell32.dll");
return FALSE;
}
WindhawkUtils::SYMBOL_HOOK hook = {
{
#ifdef _WIN64
L"__int64 __cdecl AboutDlgProc(struct HWND__ *,unsigned int,unsigned __int64,__int64)"
#else
L"int __stdcall AboutDlgProc(struct HWND__ *,unsigned int,unsigned int,long)"
#endif
},
(void **)&AboutDlgProc_orig,
(void *)AboutDlgProc_hook,
false
};
if (!WindhawkUtils::HookSymbols(
hShell32,
&hook,
1
))
{
Wh_Log(L"Failed to hook AboutDlgProc");
return FALSE;
}
return TRUE;
}
void Wh_ModSettingsChanged(void)
{
LoadSettings();
}