On 3/18/20 4:09 PM, Gabriel Ivăncescu wrote:
On 17/03/2020 19:24, Nikolay Sivov wrote:
On 3/17/20 7:50 PM, Gabriel Ivăncescu wrote:
On 17/03/2020 18:28, Nikolay Sivov wrote:
On 3/17/20 7:07 PM, Gabriel Ivăncescu wrote:
+/***********************************************************************
- Win8 info, reported if app doesn't provide compat GUID in
manifest.
- */
+static const RTL_OSVERSIONINFOEXW windows8_version_data = +{ + sizeof(RTL_OSVERSIONINFOEXW), 6, 2, 0x23f0, VER_PLATFORM_WIN32_NT, + {0}, 0, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0 +};
+/***********************************************************************
- Windows versions that need compatibility GUID specified in
manifest
- in order to be reported by the APIs.
- */
+static const struct +{ + RTL_OSVERSIONINFOEXW info; + GUID guid; +} version_data[] = +{ + /* Windows 8.1 */ + { + { + sizeof(RTL_OSVERSIONINFOEXW), 6, 3, 0x2580, VER_PLATFORM_WIN32_NT, + {0}, 0, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0 + },
{0x1f676c76,0x80e1,0x4239,{0x95,0xbb,0x83,0xd0,0xf6,0xd0,0xda,0x78}} + }, + /* Windows 10 */ + { + { + sizeof(RTL_OSVERSIONINFOEXW), 10, 0, 0x42ee, VER_PLATFORM_WIN32_NT, + {0}, 0, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0 + },
{0x8e0f7a12,0xbfb3,0x4fe8,{0xb9,0xa5,0x48,0xfd,0x50,0xa1,0x5a,0x9a}} + } +};
For that you only need to store 3 values - major/minor/build.
Ah alright, I just copy-pasted the entires from ntdll.
+/***********************************************************************
- Holds the current version (including compatibility mode).
- Call init_current_version before using it.
- */
+static RTL_OSVERSIONINFOEXW current_version;
+/******************************************************************************
- * init_current_version
- Initialize the current_version variable.
- For compatibility, Windows 8.1 and later report Win8 version
unless the app
- has a manifest that confirms its compatibility with newer
versions of Windows.
- */
+static BOOL CALLBACK init_current_version_callback(PINIT_ONCE init_once, PVOID parameter, PVOID *context) +{
Should it actually be static and initialized once? What happens if you activate another context dynamically?
I actually have no idea, didn't know you can do that. I'm somewhat unfamiliar with activation context APIs. What API should I be using to test this?
There are functions to create, activate and deactivate contexts. We use that in tests for example.
So, I tested with the ACTCTX_FLAG_SET_PROCESS_DEFAULT flag for CreateActCtx, followed by ActivateActCtx, at the beginning of the test.
Just to make sure, I retrieved the GUIDs with CompatibilityInformationInActivationContext and they seemed in order, so the manifest was loaded correctly and the activation context pushed. i.e. it returned the same GUIDs as if the app itself had the manifest, without pushing it manually on the stack.
However, GetVersionEx reported Windows 8, as if no manifest. So I suspect it gets cached at startup somewhere... and any further activation context changes won't matter.
Any idea of a good place to do that? It must be a point where the default activation context become available but application code hasn't run yet. Would DllMain for kernelbase be a good place to cache it?
P.S. forgot to mention. This is different from other use cases we have, window classes or COM classes data is dynamic, functions will be using current context intentionally.
Thanks, Gabriel