mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-12 18:41:01 -06:00
This pull request reintroduces aliases for `VkKeyScanW`, `MapVirtualKeyW` and `GetKeyState` that redirect through ConIoSrv on OneCore devices. We made an assertion in PR !7096375 that those APIs were hosted in an extension APIset that was present on all OneCore devices. It turned out that this was _incorrect_: that APIset extension is only hosted on OneCoreUAP and above. This would not be a problem save for NanoServer. NanoServer is built on top of OneCore. As Nano is a container host OS, it is primarily interfaced vith via ConPTY... which exercises the VkKeyScanW/MapVirtualKeyW codepaths quite a bit. Those APIs started returning invalid data, which caused us to convert all incoming keyboard events into numpad events. This didn't prove to be an issue for CMD or PowerShell (weirdly,) but it did prove to be an issue for Redis. Unfortunately, Redis is exactly the sort of thing you might want to run in a container. Reintroducing these aliases was complicated because we took the opportunity to remove all of IInputServices (!7105348), which was a wrapper around some code that would choose Win32 or OneCore depending on the runtime environment. I made the choice (with the help of Leonard Hecker) to reimplement these functions in a different way: always call the delay-loaded version, and then on OneCore editions check the return value and error code to ssee if we hit a delay load failure. It incurs a minor cost, but all of the delay loads are in-proc and do not require us to make a syscall, so that cost is negligible. Part of this new implementation requires us to change _all conhost internal callers_ to use "OneCoreSafe" versions of those APIs. We can't redirect the user32 versions out of the way and usurp their import symbols, so this commit also introduces some warning defines. If you use VkKeyScanW (and friends), you _should_ get a linker error. Assuming HostAndPropsheetIncludes has been included. It very well may not have been included. Fixes MSFT-40435912 Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev 949e8dfc07f122520c6a74412329a6f7e77d19c5
76 lines
2.2 KiB
C++
76 lines
2.2 KiB
C++
// Copyright (c) Microsoft Corporation
|
|
// Licensed under the MIT license.
|
|
|
|
#include "precomp.h"
|
|
#include "../inc/VtApiRedirection.hpp"
|
|
#include "../onecore/ConIoSrvComm.hpp"
|
|
#pragma hdrstop
|
|
|
|
// The project include file defines these to be invalid symbols
|
|
// to clue in developers across the project not to use them.
|
|
//
|
|
// We have to use them here.
|
|
#undef VkKeyScanW
|
|
#undef MapVirtualKeyW
|
|
#undef GetKeyState
|
|
|
|
UINT OneCoreSafeMapVirtualKeyW(_In_ UINT uCode, _In_ UINT uMapType)
|
|
{
|
|
auto ret{ MapVirtualKeyW(uCode, uMapType) };
|
|
#ifdef BUILD_ONECORE_INTERACTIVITY
|
|
if (ret == 0)
|
|
{
|
|
const auto lastError{ GetLastError() };
|
|
if (lastError == ERROR_PROC_NOT_FOUND || lastError == ERROR_DELAY_LOAD_FAILED)
|
|
{
|
|
if (auto conIoSrvComm{ Microsoft::Console::Interactivity::OneCore::ConIoSrvComm::GetConIoSrvComm() })
|
|
{
|
|
SetLastError(0);
|
|
ret = conIoSrvComm->ConIoMapVirtualKeyW(uCode, uMapType);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
SHORT OneCoreSafeVkKeyScanW(_In_ WCHAR ch)
|
|
{
|
|
auto ret{ VkKeyScanW(ch) };
|
|
#ifdef BUILD_ONECORE_INTERACTIVITY
|
|
if (ret == -1)
|
|
{
|
|
const auto lastError{ GetLastError() };
|
|
if (lastError == ERROR_PROC_NOT_FOUND || lastError == ERROR_DELAY_LOAD_FAILED)
|
|
{
|
|
if (auto conIoSrvComm{ Microsoft::Console::Interactivity::OneCore::ConIoSrvComm::GetConIoSrvComm() })
|
|
{
|
|
SetLastError(0);
|
|
ret = conIoSrvComm->ConIoVkKeyScanW(ch);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
SHORT OneCoreSafeGetKeyState(_In_ int nVirtKey)
|
|
{
|
|
auto ret{ GetKeyState(nVirtKey) };
|
|
#ifdef BUILD_ONECORE_INTERACTIVITY
|
|
if (ret == 0)
|
|
{
|
|
const auto lastError{ GetLastError() };
|
|
if (lastError == ERROR_PROC_NOT_FOUND || lastError == ERROR_DELAY_LOAD_FAILED)
|
|
{
|
|
if (auto conIoSrvComm{ Microsoft::Console::Interactivity::OneCore::ConIoSrvComm::GetConIoSrvComm() })
|
|
{
|
|
SetLastError(0);
|
|
ret = conIoSrvComm->ConIoGetKeyState(nVirtKey);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|