New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Print Operating System version to log #5870
Conversation
Have you looked into this? It seems like using a manifest, even tho it would work, is still deprecated. Getting the string from the kernel seems like plenty sufficient for what we need in rpcs3. "To obtain the full version number for the operating system, call the GetFileVersionInfo function on one of the system DLLs, such as Kernel32.dll, then call VerQueryValue to obtain the \StringFileInfo\\ProductVersion subblock of the file version information." |
The GetVersionEx function is deprecated because developers used it to check whether the operating system would support certain feature ("it's Win10 or newer, it must support X"), and Microsoft hated that as it wants to reserve right to introduce or remove OS features with any update. You can ignore the warning and use that function regardless as long as you know the limitations it has, it's not going to be removed afaik. And thanks for that tip, I'll check it out once I got some time. |
@MSuih Does rpcs3 manifest exes? If not, |
Nope, but if someone were kind enough to create one I woudn't have to juggle through this mess of a C API just to get a version identifier out of it. Sheesh, 3 functions that each require an error check and a bunch of temporary variables just for one version string. |
Actually it looks like manifest is embedded in rpcs3.exe as a resource by default. EDIT: Added manifest.zip to rpcs3->Properties->Manifest Tool->Input and Output->Additional manifest files. DxDiag Os string: Windows 10 Education 64-bit (10.0, Build 17763) (17763.rs5_release.180914-1434) |
Damn, was it really that easy? I thought I'd have to modify the .rc file and do all sorts of other changes. Thank you man, I got it to compile on my end. Since I don't have Visual Studio installed I'll push my current changes and see tomorrow how MSVC reacts to this when compiling with the solution files. It probably still needs some tinkering so that compiler will use the manifest file properly. |
@MSuih for MSVC you need to add additional manifest file trough properties. Here is redacted rpcs3_vcxproj.zip vcxproj file. |
I think I found a more lightweight solution and it does not require manifest.
Used PEB members are supported since first WinXP version so unless someone manages to run rpcs3 on something older this will always get the correct version. Also as a bonus, this will return correct version of windows even when run in compatibility mode while GetVersionEx will return target of compatibility version. EDIT: I am not sure how to interpret service pack version member |
That looks very promising! I do wonder about that last paragraph tho. The goal here is to know what users are doing exactly, so I don't think hiding them running compat mode should help. We would want to know. So as long as it produces the true winver AND tells whether or not compat mode for the app is running, it seems quite good to me. |
Also, the current version with the updated manifest still doesn't report the right version on win10. |
The manifest itself is working, it's just that it's only recognized if you're compiling by using cmake which requires an slightly uncommon development environment. (Or maybe you're using some other compiler which doesn't add the manifest to the exe automatically?) I'll look into the solution file once I have some time, that should get it to work for most people. As for the PEB stuff, I still prefer my current implementation over that. But I'm thinking about adding it as an additional check and comparing the two values to detect compatibility mode or missing manifest file. |
Either can be used to determine if in compat mode. If any flags are set then compat mode is enabled. I tested for all modes available for this executable (Vista, Vista SP1, Vista SP2, 7, 8). P.S. Anyone knows where is EDIT: It does not matter which member to use for compat but |
Still not done, but it's fairly close now. I decided to use the PEB version in the end, seems like it provides everything we need and doesn't require the use of depricated functionality. I don't know what is going on with the Edit: So yeah I'll look more into this later, but if you have suggestions/comments feel free to state them. Would also love to get the version string from someone who's using a Windows version with service pack installed. |
03e4b35
to
0c368de
Compare
Might as well remove the WIP label since I don't really know what to add anymore. I can't really test the service pack stuff on my own anyways. |
@MSuih Try #include "subauth.h" // For _UNICODE_STRING
...
const DWORD peb_offset = 0x60;
const INT_PTR peb = __readgsqword(peb_offset);
const DWORD version_major = *reinterpret_cast<const DWORD*>(peb + 0x0118);
const DWORD version_minor = *reinterpret_cast<const DWORD*>(peb + 0x011c);
const WORD build = *reinterpret_cast<const WORD*>(peb + 0x0120);
const _UNICODE_STRING service_pack = *reinterpret_cast<const _UNICODE_STRING*>(peb + 0x02E8);
const u64 compatibility_mode = *reinterpret_cast<const u64*>(peb + 0x02D0);
char service_pack_str[32]{"Not Installed"}; // Arbitrary buffer size; Need to test what is Buffer value on Windows with SP
if (service_pack.Length > 0u)
{
wcstombs(service_pack_str, service_pack.Buffer, service_pack.Length);// If no SP then it points to L'\0'
service_pack_str[service_pack.Length] = '\0';
}
fmt::append(
output, "Operating system: Windows, Major: %u, Minor: %u, Build: %u, Service Pack: %s, Compatibility mode: %llu", version_major, version_minor, build, service_pack_str, compatibility_mode); In my case, the underlying Buffer is '\0'. Needs to be tested on Win with Sp to be sure it has correct value. |
Credit to @Maximilian578 for help
This mismatch of various strings is making my head hurt, hopefully I didn't mess anything up when converting. |
Btw, it can be trivially implemented in a cross-platform way using Qt if you can afford such dependency for Utilities. |
Qt is intentionally kept separate from rest of the emulator in case f.ex. someone wants to do UI-less version of rpcs3 or switch to another UI framework. |
The idea behind this is to get some more data about the operating system RPCS3 is ran on, so that issues like #5621 and #5799 we could potentially determine which system updates are causing issues. I also added an implementation for Linux/BSD/Mac, maybe that will prove useful some day. Also includes a check for compatibility modes, in case someone decides to use one for any reason.