(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:
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user