(Win32 refresh) GetFileInformation, DebugInfoHunt

DebugInfoHunt was also updated since GetFileInformation directly uses it.

- GetMemoryDebugInfo is updated as GlobalMemoryStatus is deprecated.
- GetWindowsVersionDebugInfo is updated to use RtlGetVersion.
- GetFileInformation updated to use vector and string, as well as const correctness and modern  Windows methods. Mostly removing Win9x-XP compatibility code.
- Also gets rid of some workarounds aimed at XP era versions of Visual Studio.

Fix a mistake in Windows version detection logic
This commit is contained in:
sukibaby
2025-03-02 08:51:21 -08:00
committed by teejusb
parent 8f8064c8fa
commit 3f348117e2
3 changed files with 90 additions and 182 deletions
+55 -84
View File
@@ -4,6 +4,7 @@
#include "RageUtil.h"
#include "VideoDriverInfo.h"
#include "RegistryAccess.h"
#include "ErrorStrings.h"
#include <vector>
@@ -19,13 +20,19 @@ static void LogVideoDriverInfo( VideoDriverInfo info )
static void GetMemoryDebugInfo()
{
MEMORYSTATUS mem;
GlobalMemoryStatus(&mem);
LOG->Info("Memory: %imb total, %imb swap (%imb swap avail)",
mem.dwTotalPhys / 1048576,
mem.dwTotalPageFile / 1048576,
mem.dwAvailPageFile / 1048576);
MEMORYSTATUSEX mem;
mem.dwLength = sizeof(mem);
if (GlobalMemoryStatusEx(&mem))
{
LOG->Info("Memory: %lluMB total, %lluMB swap (%lluMB swap avail)",
mem.ullTotalPhys / (1024 * 1024),
mem.ullTotalPageFile / (1024 * 1024),
mem.ullAvailPageFile / (1024 * 1024));
}
else
{
LOG->Warn("GlobalMemoryStatusEx failed: %s", werr_ssprintf(GetLastError(), "GlobalMemoryStatusEx").c_str());
}
}
static void GetDisplayDriverDebugInfo()
@@ -139,86 +146,50 @@ static void GetDriveDebugInfo()
static void GetWindowsVersionDebugInfo()
{
// Detect operating system.
OSVERSIONINFO ovi;
ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
#pragma warning( push )
#pragma warning( disable : 4996 )
if (!GetVersionEx(&ovi))
#pragma warning( pop )
typedef LONG(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
HMODULE hMod = GetModuleHandleW(L"ntdll.dll");
if (hMod)
{
LOG->Info("GetVersionEx failed!");
return;
}
RtlGetVersionPtr pRtlGetVersion = (RtlGetVersionPtr)GetProcAddress(hMod, "RtlGetVersion");
if (pRtlGetVersion)
{
OSVERSIONINFOEXW osvi = { 0 };
osvi.dwOSVersionInfoSize = sizeof(osvi);
if (pRtlGetVersion((PRTL_OSVERSIONINFOW)&osvi) == 0)
{
RString Ver = ssprintf("Windows %lu.%lu (", osvi.dwMajorVersion, osvi.dwMinorVersion);
if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1)
{
Ver += "Win7";
}
else if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 2)
{
Ver += "Win8";
}
else if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 3)
{
Ver += "Win8.1";
}
else if (osvi.dwMajorVersion == 10 && osvi.dwMinorVersion == 0 && osvi.dwBuildNumber < 22000)
{
Ver += "Win10";
}
else if (osvi.dwMajorVersion == 10 && osvi.dwMinorVersion == 0 && osvi.dwBuildNumber >= 22000)
{
Ver += "Win11";
}
else
{
Ver += "unknown";
}
RString Ver = ssprintf("Windows %i.%i (", ovi.dwMajorVersion, ovi.dwMinorVersion);
if(ovi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
{
if(ovi.dwMinorVersion == 0)
Ver += "Win95";
else if(ovi.dwMinorVersion == 10)
Ver += "Win98";
else if(ovi.dwMinorVersion == 90)
Ver += "WinME";
else
Ver += "unknown 9x-based";
Ver += ssprintf(") build %lu [%s]", osvi.dwBuildNumber, osvi.szCSDVersion);
LOG->Info("%s", Ver.c_str());
return;
}
}
}
else if(ovi.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
if(ovi.dwMajorVersion == 4 && ovi.dwMinorVersion == 0)
Ver += "WinNT 4.0";
else if(ovi.dwMajorVersion == 5 && ovi.dwMinorVersion == 0)
Ver += "Win2000";
else if(ovi.dwMajorVersion == 5 && ovi.dwMinorVersion == 1)
Ver += "WinXP";
else if(ovi.dwMajorVersion == 5 && ovi.dwMinorVersion == 2)
{
Ver += "WinServer2003";
// todo: check for R2
/*
if(GetSystemMetrics(SM_SERVERR2) != 0)
Ver += "R2";
*/
}
else if(ovi.dwMajorVersion == 6 && ovi.dwMinorVersion == 0)
{
Ver += "Vista";
// todo: make this check work
/*
if(ovi.wProductType == VER_NT_WORKSTATION)
Ver += "Vista";
else
Ver += "WinServer2008";
*/
}
else if(ovi.dwMajorVersion == 6 && ovi.dwMinorVersion == 1)
{
Ver += "Win7";
// todo: make this check work
/*
if(ovi.wProductType == VER_NT_WORKSTATION)
Ver += "Win7";
else
Ver += "WinServer2008 R2";
*/
}
else if(ovi.dwMajorVersion == 6 && ovi.dwMinorVersion == 2)
{
Ver += "Win8";
// todo: make this check work
/*
if(ovi.wProductType == VER_NT_WORKSTATION)
Ver += "Win7";
else
Ver += "WinServer2008 R2";
*/
}
else
Ver += "unknown NT-based";
} else Ver += "???";
Ver += ssprintf(") build %i [%s]", ovi.dwBuildNumber & 0xffff, ovi.szCSDVersion);
LOG->Info("%s", Ver.c_str());
LOG->Info("RtlGetVersion failed!");
}
static void GetSoundDriverDebugInfo()
+33 -96
View File
@@ -8,28 +8,27 @@
#include <sys/stat.h>
#include <windows.h>
#include <tlhelp32.h>
#include <vector>
#include <string>
#pragma comment(lib, "version.lib")
bool GetFileVersion( RString sFile, RString &sOut )
bool GetFileVersion(const RString &sFile, RString &sOut)
{
do {
// Cast away const to work around header bug in VC6.
DWORD ignore;
DWORD iSize = GetFileVersionInfoSize( const_cast<char *>(sFile.c_str()), &ignore );
DWORD iSize = GetFileVersionInfoSize(sFile.c_str(), &ignore);
if( !iSize )
break;
RString VersionBuffer( iSize, ' ' );
// Also VC6:
if( !GetFileVersionInfo( const_cast<char *>(sFile.c_str()), 0, iSize, const_cast<char *>(VersionBuffer.c_str()) ) )
std::vector<char> VersionBuffer(iSize);
if (!GetFileVersionInfo(sFile.c_str(), 0, iSize, VersionBuffer.data()))
break;
WORD *iTrans;
UINT iTransCnt;
if( !VerQueryValue( (void *) VersionBuffer.c_str() , "\\VarFileInfo\\Translation",
(void **) &iTrans, &iTransCnt ) )
if( !VerQueryValue(VersionBuffer.data(), "\\VarFileInfo\\Translation", (void**)&iTrans, &iTransCnt) )
break;
if( iTransCnt == 0 )
@@ -38,10 +37,8 @@ bool GetFileVersion( RString sFile, RString &sOut )
char *str;
UINT len;
RString sRes = ssprintf( "\\StringFileInfo\\%04x%04x\\FileVersion",
iTrans[0], iTrans[1] );
if( !VerQueryValue( (void *) VersionBuffer.c_str(), (char *) sRes.c_str(),
(void **) &str, &len ) || len < 1)
RString sRes = ssprintf("\\StringFileInfo\\%04x%04x\\FileVersion", iTrans[0], iTrans[1]);
if (!VerQueryValue(VersionBuffer.data(), sRes.c_str(), (void**)&str, &len) || len < 1)
break;
sOut = RString( str, len-1 );
@@ -49,7 +46,7 @@ bool GetFileVersion( RString sFile, RString &sOut )
// Get the size and date.
struct stat st;
if( stat( sFile, &st ) != -1 )
if (stat(sFile.c_str(), &st) != -1)
{
struct tm t;
gmtime_r( &st.st_mtime, &t );
@@ -61,18 +58,18 @@ bool GetFileVersion( RString sFile, RString &sOut )
return true;
}
RString FindSystemFile( RString sFile )
RString FindSystemFile(const RString& sFile)
{
char szWindowsPath[MAX_PATH];
GetWindowsDirectory( szWindowsPath, MAX_PATH );
const char *szPaths[] =
{
"/system32/",
"/system32/drivers/",
"/system/",
"/system/drivers/",
"/",
"\\system32\\",
"\\system32\\drivers\\",
"\\system\\",
"\\system\\drivers\\",
"\\",
nullptr
};
@@ -80,7 +77,7 @@ RString FindSystemFile( RString sFile )
{
RString sPath = ssprintf( "%s%s%s", szWindowsPath, szPaths[i], sFile.c_str() );
struct stat buf;
if( !stat(sPath, &buf) )
if (!stat(sPath.c_str(), &buf))
return sPath;
}
@@ -91,84 +88,24 @@ RString FindSystemFile( RString sFile )
* returned and an error message is placed in sName. */
bool GetProcessFileName( uint32_t iProcessID, RString &sName )
{
/* This method works in everything except for NT4, and only uses
* kernel32.lib functions. */
do {
HANDLE hSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, iProcessID );
if( hSnap == nullptr )
{
sName = werr_ssprintf( GetLastError(), "CreateToolhelp32Snapshot" );
break;
}
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, iProcessID);
if (hSnap == INVALID_HANDLE_VALUE)
{
sName = werr_ssprintf(GetLastError(), "CreateToolhelp32Snapshot");
return false;
}
MODULEENTRY32 me;
ZERO( me );
me.dwSize = sizeof(MODULEENTRY32);
bool bRet = !!Module32First( hSnap, &me );
CloseHandle( hSnap );
if( bRet )
{
sName = me.szExePath;
return true;
}
sName = werr_ssprintf( GetLastError(), "Module32First" );
} while(0);
// This method only works in NT/2K/XP.
do {
static HINSTANCE hPSApi = nullptr;
typedef DWORD (WINAPI* pfnGetProcessImageFileNameA)(HANDLE hProcess, LPSTR lpImageFileName, DWORD nSize);
static pfnGetProcessImageFileNameA pGetProcessImageFileName = nullptr;
static bool bTried = false;
if( !bTried )
{
bTried = true;
hPSApi = LoadLibrary("psapi.dll");
if( hPSApi == nullptr )
{
sName = werr_ssprintf( GetLastError(), "LoadLibrary" );
break;
}
else
{
pGetProcessImageFileName = (pfnGetProcessImageFileNameA) GetProcAddress( hPSApi, "GetProcessImageFileNameA" );
if( pGetProcessImageFileName == nullptr )
{
sName = werr_ssprintf( GetLastError(), "GetProcAddress" );
break;
}
}
}
if( pGetProcessImageFileName != nullptr )
{
HANDLE hProc = OpenProcess( PROCESS_VM_READ|PROCESS_QUERY_INFORMATION, FALSE, iProcessID );
if( hProc == nullptr )
{
sName = werr_ssprintf( GetLastError(), "OpenProcess" );
break;
}
char buf[1024];
int iRet = pGetProcessImageFileName( hProc, buf, sizeof(buf) );
CloseHandle( hProc );
if( iRet )
{
if( iRet == sizeof(buf) )
buf[iRet-1] = 0;
sName = buf;
return true;
}
sName = werr_ssprintf( GetLastError(), "GetProcessImageFileName" );
}
} while(0);
MODULEENTRY32 me;
me.dwSize = sizeof(MODULEENTRY32);
if (Module32First(hSnap, &me))
{
sName = me.szExePath;
CloseHandle(hSnap);
return true;
}
CloseHandle(hSnap);
sName = werr_ssprintf(GetLastError(), "Module32First");
return false;
}
+2 -2
View File
@@ -5,8 +5,8 @@
#include <cstdint>
bool GetFileVersion( RString fsFile, RString &sOut );
RString FindSystemFile( RString sFile );
bool GetFileVersion( const RString& sFile, RString& sOut );
RString FindSystemFile( const RString& sFile );
bool GetProcessFileName( uint32_t iProcessID, RString &sName );
#endif