[PATCH v2 1/3] kernelbase: Implement compatibility mode for GetVersionEx.

Nikolay Sivov nsivov at codeweavers.com
Wed Mar 18 08:57:13 CDT 2020



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




More information about the wine-devel mailing list