On Tue Oct 11 11:27:57 2022 +0000, Jinoh Kang wrote:
It reads a shared variable *twice* without atomic access. If the first read resulted in a nonzero value but the second read resulted in zero, the function will return zero as-is instead of NTUSER_DPI_UNAWARE. Unless I have mistaken, this can happen if the two reads are reordered, notwithstanding the fact that the variable cannot normally transition from a nonzero value back to zero. The variable cannot be made to default to NTUSER_DPI_UNAWARE without an extra out-of-band flag variable, since `NtUserSetProcessDpiAwarenessContext` has to distinguish between unset state (represented as zero) and set state (represented as nonzero). The reason why the process-wide DPI awareness state cannot be changed once set is that doing so will result in inconsistent DPI-aware behaviour between different application components each of which calls `NtUserGetProcessDpiAwarenessContext` to fetch the DPI awareness status. Also, the load-acquire is paired with `InterlockedCompareExchange` in `NtUserZetProcessDpiAwarenessContext` and is also necessary to prevent reordering across successive `NtUserGetProcessDpiAwarenessContext` calls.
Right, but can the two reads really be reordered here?