Merged PR 7705187: [Git2Git] Merged PR 7693103: Reintroduce OneCore redirects for MapVKeyW/VkKeyScanW/GetKeyState

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
This commit is contained in:
Dustin Howett 2022-08-10 21:14:52 +00:00
parent eb1d6b599e
commit a94e508010
29 changed files with 468 additions and 94 deletions

View File

@ -52,35 +52,35 @@ ULONG GetControlKeyState(const LPARAM lParam)
{ {
ULONG ControlKeyState = 0; ULONG ControlKeyState = 0;
if (GetKeyState(VK_LMENU) & KEY_PRESSED) if (OneCoreSafeGetKeyState(VK_LMENU) & KEY_PRESSED)
{ {
ControlKeyState |= LEFT_ALT_PRESSED; ControlKeyState |= LEFT_ALT_PRESSED;
} }
if (GetKeyState(VK_RMENU) & KEY_PRESSED) if (OneCoreSafeGetKeyState(VK_RMENU) & KEY_PRESSED)
{ {
ControlKeyState |= RIGHT_ALT_PRESSED; ControlKeyState |= RIGHT_ALT_PRESSED;
} }
if (GetKeyState(VK_LCONTROL) & KEY_PRESSED) if (OneCoreSafeGetKeyState(VK_LCONTROL) & KEY_PRESSED)
{ {
ControlKeyState |= LEFT_CTRL_PRESSED; ControlKeyState |= LEFT_CTRL_PRESSED;
} }
if (GetKeyState(VK_RCONTROL) & KEY_PRESSED) if (OneCoreSafeGetKeyState(VK_RCONTROL) & KEY_PRESSED)
{ {
ControlKeyState |= RIGHT_CTRL_PRESSED; ControlKeyState |= RIGHT_CTRL_PRESSED;
} }
if (GetKeyState(VK_SHIFT) & KEY_PRESSED) if (OneCoreSafeGetKeyState(VK_SHIFT) & KEY_PRESSED)
{ {
ControlKeyState |= SHIFT_PRESSED; ControlKeyState |= SHIFT_PRESSED;
} }
if (GetKeyState(VK_NUMLOCK) & KEY_TOGGLED) if (OneCoreSafeGetKeyState(VK_NUMLOCK) & KEY_TOGGLED)
{ {
ControlKeyState |= NUMLOCK_ON; ControlKeyState |= NUMLOCK_ON;
} }
if (GetKeyState(VK_SCROLL) & KEY_TOGGLED) if (OneCoreSafeGetKeyState(VK_SCROLL) & KEY_TOGGLED)
{ {
ControlKeyState |= SCROLLLOCK_ON; ControlKeyState |= SCROLLLOCK_ON;
} }
if (GetKeyState(VK_CAPITAL) & KEY_TOGGLED) if (OneCoreSafeGetKeyState(VK_CAPITAL) & KEY_TOGGLED)
{ {
ControlKeyState |= CAPSLOCK_ON; ControlKeyState |= CAPSLOCK_ON;
} }

View File

@ -25,7 +25,7 @@ Selection::KeySelectionEventResult Selection::HandleKeySelectionEvent(const INPU
FAIL_FAST_IF(!IsInSelectingState()); FAIL_FAST_IF(!IsInSelectingState());
const auto wVirtualKeyCode = pInputKeyInfo->GetVirtualKey(); const auto wVirtualKeyCode = pInputKeyInfo->GetVirtualKey();
const auto ctrlPressed = WI_IsFlagSet(GetKeyState(VK_CONTROL), KEY_PRESSED); const auto ctrlPressed = WI_IsFlagSet(OneCoreSafeGetKeyState(VK_CONTROL), KEY_PRESSED);
// if escape or ctrl-c, cancel selection // if escape or ctrl-c, cancel selection
if (!IsMouseButtonDown()) if (!IsMouseButtonDown())
@ -611,7 +611,7 @@ bool Selection::HandleKeyboardLineSelectionEvent(const INPUT_KEY_INFO* const pIn
// - <none> // - <none>
void Selection::CheckAndSetAlternateSelection() void Selection::CheckAndSetAlternateSelection()
{ {
_fUseAlternateSelection = !!(GetKeyState(VK_MENU) & KEY_PRESSED); _fUseAlternateSelection = !!(OneCoreSafeGetKeyState(VK_MENU) & KEY_PRESSED);
} }
// Routine Description: // Routine Description:
@ -904,7 +904,7 @@ bool Selection::_HandleMarkModeSelectionNav(const INPUT_KEY_INFO* const pInputKe
} }
// see if shift is down. if so, we're extending the selection. otherwise, we're resetting the anchor // see if shift is down. if so, we're extending the selection. otherwise, we're resetting the anchor
if (GetKeyState(VK_SHIFT) & KEY_PRESSED) if (OneCoreSafeGetKeyState(VK_SHIFT) & KEY_PRESSED)
{ {
// if we're just starting to "extend" our selection from moving around as a cursor // if we're just starting to "extend" our selection from moving around as a cursor
// then attempt to set the alternate selection state based on the ALT key right now // then attempt to set the alternate selection state based on the ALT key right now

View File

@ -153,7 +153,7 @@ using Microsoft::Console::Interactivity::ServiceLocator;
} }
else else
{ {
const auto zeroVkeyData = VkKeyScanW(0); const auto zeroVkeyData = OneCoreSafeVkKeyScanW(0);
const auto zeroVKey = LOBYTE(zeroVkeyData); const auto zeroVKey = LOBYTE(zeroVkeyData);
const auto zeroControlKeyState = HIBYTE(zeroVkeyData); const auto zeroControlKeyState = HIBYTE(zeroVkeyData);

View File

@ -15,6 +15,8 @@
#include <cctype> #include <cctype>
#include "../../interactivity/inc/VtApiRedirection.hpp"
#include "../../inc/consoletaeftemplates.hpp" #include "../../inc/consoletaeftemplates.hpp"
using namespace WEX::Common; using namespace WEX::Common;
@ -167,9 +169,9 @@ class ClipboardTests
keyEvent.reset(static_cast<KeyEvent* const>(events.front().release())); keyEvent.reset(static_cast<KeyEvent* const>(events.front().release()));
events.pop_front(); events.pop_front();
const auto keyState = VkKeyScanW(wch); const auto keyState = OneCoreSafeVkKeyScanW(wch);
VERIFY_ARE_NOT_EQUAL(-1, keyState); VERIFY_ARE_NOT_EQUAL(-1, keyState);
const auto virtualScanCode = static_cast<WORD>(MapVirtualKeyW(LOBYTE(keyState), MAPVK_VK_TO_VSC)); const auto virtualScanCode = static_cast<WORD>(OneCoreSafeMapVirtualKeyW(LOBYTE(keyState), MAPVK_VK_TO_VSC));
VERIFY_ARE_EQUAL(wch, keyEvent->GetCharData()); VERIFY_ARE_EQUAL(wch, keyEvent->GetCharData());
VERIFY_ARE_EQUAL(isKeyDown, keyEvent->IsKeyDown()); VERIFY_ARE_EQUAL(isKeyDown, keyEvent->IsKeyDown());
@ -206,9 +208,9 @@ class ClipboardTests
events.pop_front(); events.pop_front();
const short keyScanError = -1; const short keyScanError = -1;
const auto keyState = VkKeyScanW(wch); const auto keyState = OneCoreSafeVkKeyScanW(wch);
VERIFY_ARE_NOT_EQUAL(keyScanError, keyState); VERIFY_ARE_NOT_EQUAL(keyScanError, keyState);
const auto virtualScanCode = static_cast<WORD>(MapVirtualKeyW(LOBYTE(keyState), MAPVK_VK_TO_VSC)); const auto virtualScanCode = static_cast<WORD>(OneCoreSafeMapVirtualKeyW(LOBYTE(keyState), MAPVK_VK_TO_VSC));
if (std::isupper(wch)) if (std::isupper(wch))
{ {
@ -222,9 +224,9 @@ class ClipboardTests
keyEvent2.reset(static_cast<KeyEvent* const>(events.front().release())); keyEvent2.reset(static_cast<KeyEvent* const>(events.front().release()));
events.pop_front(); events.pop_front();
const auto keyState2 = VkKeyScanW(wch); const auto keyState2 = OneCoreSafeVkKeyScanW(wch);
VERIFY_ARE_NOT_EQUAL(keyScanError, keyState2); VERIFY_ARE_NOT_EQUAL(keyScanError, keyState2);
const auto virtualScanCode2 = static_cast<WORD>(MapVirtualKeyW(LOBYTE(keyState2), MAPVK_VK_TO_VSC)); const auto virtualScanCode2 = static_cast<WORD>(OneCoreSafeMapVirtualKeyW(LOBYTE(keyState2), MAPVK_VK_TO_VSC));
if (isKeyDown) if (isKeyDown)
{ {
@ -258,9 +260,9 @@ class ClipboardTests
{ {
const std::wstring wstr = L"\x20ac"; // € char U+20AC const std::wstring wstr = L"\x20ac"; // € char U+20AC
const auto keyState = VkKeyScanW(wstr[0]); const auto keyState = OneCoreSafeVkKeyScanW(wstr[0]);
const WORD virtualKeyCode = LOBYTE(keyState); const WORD virtualKeyCode = LOBYTE(keyState);
const auto virtualScanCode = static_cast<WORD>(MapVirtualKeyW(virtualKeyCode, MAPVK_VK_TO_VSC)); const auto virtualScanCode = static_cast<WORD>(OneCoreSafeMapVirtualKeyW(virtualKeyCode, MAPVK_VK_TO_VSC));
if (keyState == -1 || HIBYTE(keyState) == 0 /* no modifiers required */) if (keyState == -1 || HIBYTE(keyState) == 0 /* no modifiers required */)
{ {

View File

@ -39,6 +39,14 @@ typedef NTSTATUS *PNTSTATUS;
#include <winuser.h> #include <winuser.h>
#define VkKeyScanW DO_NOT_USE_VkKeyScanW_USE_OneCoreSafeVkKeyScanW
#define MapVirtualKeyW DO_NOT_USE_MapVirtualKeyW_USE_OneCoreSafeMapVirtualKeyW
#define GetKeyState DO_NOT_USE_GetKeyState_USE_OneCoreSafeGetKeyState
// This header contains some overrides for win32 APIs
// that cannot exist on OneCore
#include "../interactivity/inc/VtApiRedirection.hpp"
#include <cwchar> #include <cwchar>
// Only remaining item from w32gdip.h. There's probably a better way to do this as well. // Only remaining item from w32gdip.h. There's probably a better way to do this as well.

View File

@ -4,6 +4,7 @@
#include "precomp.h" #include "precomp.h"
#include "../inc/EventSynthesis.hpp" #include "../inc/EventSynthesis.hpp"
#include "../../types/inc/convert.hpp" #include "../../types/inc/convert.hpp"
#include "../inc/VtApiRedirection.hpp"
#pragma hdrstop #pragma hdrstop
@ -44,7 +45,7 @@ std::deque<std::unique_ptr<KeyEvent>> Microsoft::Console::Interactivity::CharToK
const unsigned int codepage) const unsigned int codepage)
{ {
const short invalidKey = -1; const short invalidKey = -1;
auto keyState = VkKeyScanW(wch); auto keyState = OneCoreSafeVkKeyScanW(wch);
if (keyState == invalidKey) if (keyState == invalidKey)
{ {
@ -110,7 +111,7 @@ std::deque<std::unique_ptr<KeyEvent>> Microsoft::Console::Interactivity::Synthes
} }
const auto vk = LOBYTE(keyState); const auto vk = LOBYTE(keyState);
const auto virtualScanCode = gsl::narrow<WORD>(MapVirtualKeyW(vk, MAPVK_VK_TO_VSC)); const auto virtualScanCode = gsl::narrow<WORD>(OneCoreSafeMapVirtualKeyW(vk, MAPVK_VK_TO_VSC));
KeyEvent keyEvent{ true, 1, LOBYTE(keyState), virtualScanCode, wch, 0 }; KeyEvent keyEvent{ true, 1, LOBYTE(keyState), virtualScanCode, wch, 0 };
// add modifier flags if necessary // add modifier flags if necessary
@ -200,7 +201,7 @@ std::deque<std::unique_ptr<KeyEvent>> Microsoft::Console::Interactivity::Synthes
break; break;
} }
const WORD virtualKey = ch - '0' + VK_NUMPAD0; const WORD virtualKey = ch - '0' + VK_NUMPAD0;
const auto virtualScanCode = gsl::narrow<WORD>(MapVirtualKeyW(virtualKey, MAPVK_VK_TO_VSC)); const auto virtualScanCode = gsl::narrow<WORD>(OneCoreSafeMapVirtualKeyW(virtualKey, MAPVK_VK_TO_VSC));
keyEvents.push_back(std::make_unique<KeyEvent>(true, keyEvents.push_back(std::make_unique<KeyEvent>(true,
1ui16, 1ui16,

View File

@ -0,0 +1,75 @@
// 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;
}

View File

@ -30,6 +30,7 @@
</ClCompile> </ClCompile>
<ClCompile Include="..\RemoteConsoleControl.cpp" /> <ClCompile Include="..\RemoteConsoleControl.cpp" />
<ClCompile Include="..\ServiceLocator.cpp" /> <ClCompile Include="..\ServiceLocator.cpp" />
<ClCompile Include="..\VtApiRedirection.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\inc\IAccessibilityNotifier.hpp" /> <ClInclude Include="..\..\inc\IAccessibilityNotifier.hpp" />
@ -41,6 +42,7 @@
<ClInclude Include="..\..\inc\ISystemConfigurationProvider.hpp" /> <ClInclude Include="..\..\inc\ISystemConfigurationProvider.hpp" />
<ClInclude Include="..\..\inc\IWindowMetrics.hpp" /> <ClInclude Include="..\..\inc\IWindowMetrics.hpp" />
<ClInclude Include="..\..\inc\Module.hpp" /> <ClInclude Include="..\..\inc\Module.hpp" />
<ClInclude Include="..\..\inc\VtApiRedirection.hpp" />
<ClInclude Include="..\..\inc\EventSynthesis.hpp" /> <ClInclude Include="..\..\inc\EventSynthesis.hpp" />
<ClInclude Include="..\ApiDetector.hpp" /> <ClInclude Include="..\ApiDetector.hpp" />
<ClInclude Include="..\HostSignalInputThread.hpp" /> <ClInclude Include="..\HostSignalInputThread.hpp" />

View File

@ -74,6 +74,9 @@
<ClInclude Include="..\..\inc\Module.hpp"> <ClInclude Include="..\..\inc\Module.hpp">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\inc\VtApiRedirection.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\EventSynthesis.hpp"> <ClInclude Include="..\..\inc\EventSynthesis.hpp">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
@ -90,4 +93,4 @@
<ItemGroup> <ItemGroup>
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" /> <Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -13,7 +13,7 @@
# Preprocessor Settings # Preprocessor Settings
# ------------------------------------- # -------------------------------------
C_DEFINES = $(C_DEFINES) -DBUILD_ONECORE_INTERACTIVITY C_DEFINES = $(C_DEFINES)
# ------------------------------------- # -------------------------------------
# Compiler Settings # Compiler Settings
@ -39,6 +39,7 @@ SOURCES = \
..\ApiDetector.cpp \ ..\ApiDetector.cpp \
..\InteractivityFactory.cpp \ ..\InteractivityFactory.cpp \
..\ServiceLocator.cpp \ ..\ServiceLocator.cpp \
..\VtApiRedirection.cpp \
..\EventSynthesis.cpp \ ..\EventSynthesis.cpp \
..\RemoteConsoleControl.cpp \ ..\RemoteConsoleControl.cpp \
..\HostSignalInputThread.cpp \ ..\HostSignalInputThread.cpp \

View File

@ -0,0 +1,33 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- VtApiRedirection.h
Abstract:
- Redefines several input-related API's that are not available on OneCore such
that they be redirected through the ServiceLocator via the IInputServices
interface.
- This ensures that all calls to these API's are executed as normal when the
console is running on big Windows, but that they are also redirected to the
Console IO Server when it is running on a OneCore system, where the OneCore
implementations live.
Author:
- HeGatta Apr.25.2017
--*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
UINT OneCoreSafeMapVirtualKeyW(_In_ UINT uCode, _In_ UINT uMapType);
SHORT OneCoreSafeVkKeyScanW(_In_ WCHAR ch);
SHORT OneCoreSafeGetKeyState(_In_ int nVirtKey);
#ifdef __cplusplus
}
#endif

View File

@ -518,6 +518,70 @@ VOID ConIoSrvComm::CleanupForHeadless(const NTSTATUS status)
return Status; return Status;
} }
[[nodiscard]] NTSTATUS ConIoSrvComm::RequestMapVirtualKey(_In_ UINT uCode, _In_ UINT uMapType, _Out_ UINT* puReturnValue)
{
NTSTATUS Status;
Status = EnsureConnection();
if (NT_SUCCESS(Status))
{
CIS_MSG Message = { 0 };
Message.Type = CIS_MSG_TYPE_MAPVIRTUALKEY;
Message.MapVirtualKeyParams.Code = uCode;
Message.MapVirtualKeyParams.MapType = uMapType;
Status = SendRequestReceiveReply(&Message);
if (NT_SUCCESS(Status))
{
*puReturnValue = Message.MapVirtualKeyParams.ReturnValue;
}
}
return Status;
}
[[nodiscard]] NTSTATUS ConIoSrvComm::RequestVkKeyScan(_In_ WCHAR wCharacter, _Out_ SHORT* psReturnValue)
{
NTSTATUS Status;
Status = EnsureConnection();
if (NT_SUCCESS(Status))
{
CIS_MSG Message = { 0 };
Message.Type = CIS_MSG_TYPE_VKKEYSCAN;
Message.VkKeyScanParams.Character = wCharacter;
Status = SendRequestReceiveReply(&Message);
if (NT_SUCCESS(Status))
{
*psReturnValue = Message.VkKeyScanParams.ReturnValue;
}
}
return Status;
}
[[nodiscard]] NTSTATUS ConIoSrvComm::RequestGetKeyState(_In_ int iVirtualKey, _Out_ SHORT* psReturnValue)
{
NTSTATUS Status;
Status = EnsureConnection();
if (NT_SUCCESS(Status))
{
CIS_MSG Message = { 0 };
Message.Type = CIS_MSG_TYPE_GETKEYSTATE;
Message.GetKeyStateParams.VirtualKey = iVirtualKey;
Status = SendRequestReceiveReply(&Message);
if (NT_SUCCESS(Status))
{
*psReturnValue = Message.GetKeyStateParams.ReturnValue;
}
}
return Status;
}
[[nodiscard]] USHORT ConIoSrvComm::GetDisplayMode() const noexcept [[nodiscard]] USHORT ConIoSrvComm::GetDisplayMode() const noexcept
{ {
return _displayMode; return _displayMode;
@ -530,6 +594,58 @@ PVOID ConIoSrvComm::GetSharedViewBase() const noexcept
#pragma endregion #pragma endregion
#pragma region IInputServices Members
UINT ConIoSrvComm::ConIoMapVirtualKeyW(UINT uCode, UINT uMapType)
{
NTSTATUS Status = STATUS_SUCCESS;
UINT ReturnValue;
Status = RequestMapVirtualKey(uCode, uMapType, &ReturnValue);
if (!NT_SUCCESS(Status))
{
ReturnValue = 0;
SetLastError(ERROR_PROC_NOT_FOUND);
}
return ReturnValue;
}
SHORT ConIoSrvComm::ConIoVkKeyScanW(WCHAR ch)
{
NTSTATUS Status = STATUS_SUCCESS;
SHORT ReturnValue;
Status = RequestVkKeyScan(ch, &ReturnValue);
if (!NT_SUCCESS(Status))
{
ReturnValue = 0;
SetLastError(ERROR_PROC_NOT_FOUND);
}
return ReturnValue;
}
SHORT ConIoSrvComm::ConIoGetKeyState(int nVirtKey)
{
NTSTATUS Status = STATUS_SUCCESS;
SHORT ReturnValue;
Status = RequestGetKeyState(nVirtKey, &ReturnValue);
if (!NT_SUCCESS(Status))
{
ReturnValue = 0;
SetLastError(ERROR_PROC_NOT_FOUND);
}
return ReturnValue;
}
#pragma endregion
[[nodiscard]] NTSTATUS ConIoSrvComm::InitializeBgfx() [[nodiscard]] NTSTATUS ConIoSrvComm::InitializeBgfx()
{ {
const auto& globals = ServiceLocator::LocateGlobals(); const auto& globals = ServiceLocator::LocateGlobals();

View File

@ -41,12 +41,19 @@ namespace Microsoft::Console::Interactivity::OneCore
[[nodiscard]] NTSTATUS RequestSetCursor(_In_ const CD_IO_CURSOR_INFORMATION* const pCdCursorInformation) const; [[nodiscard]] NTSTATUS RequestSetCursor(_In_ const CD_IO_CURSOR_INFORMATION* const pCdCursorInformation) const;
[[nodiscard]] NTSTATUS RequestUpdateDisplay(_In_ til::CoordType RowIndex) const; [[nodiscard]] NTSTATUS RequestUpdateDisplay(_In_ til::CoordType RowIndex) const;
[[nodiscard]] NTSTATUS RequestMapVirtualKey(_In_ UINT uCode, _In_ UINT uMapType, _Out_ UINT* puReturnValue);
[[nodiscard]] NTSTATUS RequestVkKeyScan(_In_ WCHAR wCharacter, _Out_ SHORT* psReturnValue);
[[nodiscard]] NTSTATUS RequestGetKeyState(_In_ int iVirtualKey, _Out_ SHORT* psReturnValue);
[[nodiscard]] USHORT GetDisplayMode() const noexcept; [[nodiscard]] USHORT GetDisplayMode() const noexcept;
PVOID GetSharedViewBase() const noexcept; PVOID GetSharedViewBase() const noexcept;
VOID CleanupForHeadless(const NTSTATUS status); VOID CleanupForHeadless(const NTSTATUS status);
UINT ConIoMapVirtualKeyW(UINT uCode, UINT uMapType);
SHORT ConIoVkKeyScanW(WCHAR ch);
SHORT ConIoGetKeyState(int nVirtKey);
[[nodiscard]] NTSTATUS InitializeBgfx(); [[nodiscard]] NTSTATUS InitializeBgfx();
[[nodiscard]] NTSTATUS InitializeWddmCon(); [[nodiscard]] NTSTATUS InitializeWddmCon();

View File

@ -214,7 +214,7 @@ void Clipboard::StoreSelectionToClipboard(const bool copyFormatting)
}; };
bool includeCRLF, trimTrailingWhitespace; bool includeCRLF, trimTrailingWhitespace;
if (WI_IsFlagSet(GetKeyState(VK_SHIFT), KEY_PRESSED)) if (WI_IsFlagSet(OneCoreSafeGetKeyState(VK_SHIFT), KEY_PRESSED))
{ {
// When shift is held, put everything in one line // When shift is held, put everything in one line
includeCRLF = trimTrailingWhitespace = false; includeCRLF = trimTrailingWhitespace = false;

View File

@ -69,7 +69,7 @@ void RetrieveKeyInfo(_In_ HWND hWnd, _Out_ PWORD pwVirtualKeyCode, _Inout_ PWORD
} }
else else
{ {
*pwVirtualKeyCode = (WORD)MapVirtualKeyW(*pwVirtualScanCode, 3); *pwVirtualKeyCode = (WORD)OneCoreSafeMapVirtualKeyW(*pwVirtualScanCode, 3);
} }
} }

View File

@ -129,9 +129,9 @@ bool HandleTerminalMouseEvent(const til::point cMousePosition,
if (IsInVirtualTerminalInputMode()) if (IsInVirtualTerminalInputMode())
{ {
const TerminalInput::MouseButtonState state{ const TerminalInput::MouseButtonState state{
WI_IsFlagSet(GetKeyState(VK_LBUTTON), KeyPressed), WI_IsFlagSet(OneCoreSafeGetKeyState(VK_LBUTTON), KeyPressed),
WI_IsFlagSet(GetKeyState(VK_MBUTTON), KeyPressed), WI_IsFlagSet(OneCoreSafeGetKeyState(VK_MBUTTON), KeyPressed),
WI_IsFlagSet(GetKeyState(VK_RBUTTON), KeyPressed) WI_IsFlagSet(OneCoreSafeGetKeyState(VK_RBUTTON), KeyPressed)
}; };
// GH#6401: VT applications should be able to receive mouse events from outside the // GH#6401: VT applications should be able to receive mouse events from outside the
@ -394,7 +394,7 @@ void HandleKeyEvent(const HWND hWnd,
if (handlingResult == Selection::KeySelectionEventResult::CopyToClipboard) if (handlingResult == Selection::KeySelectionEventResult::CopyToClipboard)
{ {
// If the ALT key is held, also select HTML as well as plain text. // If the ALT key is held, also select HTML as well as plain text.
const auto fAlsoSelectHtml = WI_IsFlagSet(GetKeyState(VK_MENU), KEY_PRESSED); const auto fAlsoSelectHtml = WI_IsFlagSet(OneCoreSafeGetKeyState(VK_MENU), KEY_PRESSED);
Clipboard::Instance().Copy(fAlsoSelectHtml); Clipboard::Instance().Copy(fAlsoSelectHtml);
return; return;
} }
@ -476,7 +476,7 @@ BOOL HandleSysKeyEvent(const HWND hWnd, const UINT Message, const WPARAM wParam,
if (Message == WM_SYSCHAR || Message == WM_SYSDEADCHAR) if (Message == WM_SYSCHAR || Message == WM_SYSDEADCHAR)
{ {
VirtualKeyCode = (WORD)MapVirtualKeyW(LOBYTE(HIWORD(lParam)), MAPVK_VSC_TO_VK_EX); VirtualKeyCode = (WORD)OneCoreSafeMapVirtualKeyW(LOBYTE(HIWORD(lParam)), MAPVK_VSC_TO_VK_EX);
} }
else else
{ {
@ -487,16 +487,16 @@ BOOL HandleSysKeyEvent(const HWND hWnd, const UINT Message, const WPARAM wParam,
Telemetry::Instance().SetUserInteractive(); Telemetry::Instance().SetUserInteractive();
// check for ctrl-esc // check for ctrl-esc
const auto bCtrlDown = GetKeyState(VK_CONTROL) & KEY_PRESSED; const auto bCtrlDown = OneCoreSafeGetKeyState(VK_CONTROL) & KEY_PRESSED;
if (VirtualKeyCode == VK_ESCAPE && if (VirtualKeyCode == VK_ESCAPE &&
bCtrlDown && !(GetKeyState(VK_MENU) & KEY_PRESSED) && !(GetKeyState(VK_SHIFT) & KEY_PRESSED)) bCtrlDown && !(OneCoreSafeGetKeyState(VK_MENU) & KEY_PRESSED) && !(OneCoreSafeGetKeyState(VK_SHIFT) & KEY_PRESSED))
{ {
return TRUE; // call DefWindowProc return TRUE; // call DefWindowProc
} }
// check for alt-f4 // check for alt-f4
if (VirtualKeyCode == VK_F4 && (GetKeyState(VK_MENU) & KEY_PRESSED) && IsInProcessedInputMode() && gci.IsAltF4CloseAllowed()) if (VirtualKeyCode == VK_F4 && (OneCoreSafeGetKeyState(VK_MENU) & KEY_PRESSED) && IsInProcessedInputMode() && gci.IsAltF4CloseAllowed())
{ {
return TRUE; // let DefWindowProc generate WM_CLOSE return TRUE; // let DefWindowProc generate WM_CLOSE
} }
@ -527,7 +527,7 @@ BOOL HandleSysKeyEvent(const HWND hWnd, const UINT Message, const WPARAM wParam,
} }
// make sure alt-space gets translated so that the system menu is displayed. // make sure alt-space gets translated so that the system menu is displayed.
if (!(GetKeyState(VK_CONTROL) & KEY_PRESSED)) if (!(OneCoreSafeGetKeyState(VK_CONTROL) & KEY_PRESSED))
{ {
if (VirtualKeyCode == VK_SPACE) if (VirtualKeyCode == VK_SPACE)
{ {
@ -633,7 +633,7 @@ BOOL HandleMouseEvent(const SCREEN_INFORMATION& ScreenInfo,
MousePosition.X /= ScreenFontSize.X; MousePosition.X /= ScreenFontSize.X;
MousePosition.Y /= ScreenFontSize.Y; MousePosition.Y /= ScreenFontSize.Y;
const auto fShiftPressed = WI_IsFlagSet(GetKeyState(VK_SHIFT), KEY_PRESSED); const auto fShiftPressed = WI_IsFlagSet(OneCoreSafeGetKeyState(VK_SHIFT), KEY_PRESSED);
// We need to try and have the virtual terminal handle the mouse's position in viewport coordinates, // We need to try and have the virtual terminal handle the mouse's position in viewport coordinates,
// not in screen buffer coordinates. It expects the top left to always be 0,0 // not in screen buffer coordinates. It expects the top left to always be 0,0
@ -731,7 +731,7 @@ BOOL HandleMouseEvent(const SCREEN_INFORMATION& ScreenInfo,
if (Message == WM_LBUTTONDOWN) if (Message == WM_LBUTTONDOWN)
{ {
// make sure message matches button state // make sure message matches button state
if (!(GetKeyState(VK_LBUTTON) & KEY_PRESSED)) if (!(OneCoreSafeGetKeyState(VK_LBUTTON) & KEY_PRESSED))
{ {
return FALSE; return FALSE;
} }
@ -828,7 +828,7 @@ BOOL HandleMouseEvent(const SCREEN_INFORMATION& ScreenInfo,
Telemetry::Instance().LogQuickEditCopyRawUsed(); Telemetry::Instance().LogQuickEditCopyRawUsed();
} }
// If the ALT key is held, also select HTML as well as plain text. // If the ALT key is held, also select HTML as well as plain text.
const auto fAlsoCopyFormatting = WI_IsFlagSet(GetKeyState(VK_MENU), KEY_PRESSED); const auto fAlsoCopyFormatting = WI_IsFlagSet(OneCoreSafeGetKeyState(VK_MENU), KEY_PRESSED);
Clipboard::Instance().Copy(fAlsoCopyFormatting); Clipboard::Instance().Copy(fAlsoCopyFormatting);
} }
else if (gci.Flags & CONSOLE_QUICK_EDIT_MODE) else if (gci.Flags & CONSOLE_QUICK_EDIT_MODE)

View File

@ -10,7 +10,7 @@
# ------------------------------------- # -------------------------------------
UNICODE = 1 UNICODE = 1
C_DEFINES = $(C_DEFINES) -DUNICODE -D_UNICODE -DFMT_HEADER_ONLY -D__INSIDE_WINDOWS C_DEFINES = $(C_DEFINES) -DUNICODE -D_UNICODE -DFMT_HEADER_ONLY -D__INSIDE_WINDOWS -DBUILD_ONECORE_INTERACTIVITY
# ------------------------------------- # -------------------------------------
# CRT Configuration # CRT Configuration

View File

@ -5,6 +5,13 @@
#include "ColorsPage.h" #include "ColorsPage.h"
#include "ColorControl.h" #include "ColorControl.h"
// The property sheet will never load on OneCore, so we do
// not need to redirect users to the OneCore safe versionf
// of these functions.
#undef VkKeyScanW
#undef MapVirtualKeyW
#undef GetKeyState
static BYTE ColorArray[4]; static BYTE ColorArray[4];
static int iColor; static int iColor;

View File

@ -14,7 +14,7 @@
# Preprocessor Settings # Preprocessor Settings
# ------------------------------------- # -------------------------------------
C_DEFINES = $(C_DEFINES) -DBUILD_ONECORE_INTERACTIVITY C_DEFINES = $(C_DEFINES)
# ------------------------------------- # -------------------------------------
# Build System Settings # Build System Settings

View File

@ -25,12 +25,30 @@
<ProjectReference Include="..\..\..\buffer\out\lib\bufferout.vcxproj"> <ProjectReference Include="..\..\..\buffer\out\lib\bufferout.vcxproj">
<Project>{0cf235bd-2da0-407e-90ee-c467e8bbc714}</Project> <Project>{0cf235bd-2da0-407e-90ee-c467e8bbc714}</Project>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\..\..\host\lib\hostlib.vcxproj">
<Project>{06ec74cb-9a12-429c-b551-8562ec954746}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\interactivity\base\lib\InteractivityBase.vcxproj"> <ProjectReference Include="..\..\..\interactivity\base\lib\InteractivityBase.vcxproj">
<Project>{06ec74cb-9a12-429c-b551-8562ec964846}</Project> <Project>{06ec74cb-9a12-429c-b551-8562ec964846}</Project>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\..\..\interactivity\win32\lib\win32.LIB.vcxproj">
<Project>{06ec74cb-9a12-429c-b551-8532ec964726}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\propslib\propslib.vcxproj">
<Project>{345fd5a4-b32b-4f29-bd1c-b033bd2c35cc}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\renderer\base\lib\base.vcxproj"> <ProjectReference Include="..\..\..\renderer\base\lib\base.vcxproj">
<Project>{af0a096a-8b3a-4949-81ef-7df8f0fee91f}</Project> <Project>{af0a096a-8b3a-4949-81ef-7df8f0fee91f}</Project>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\..\..\renderer\gdi\lib\gdi.vcxproj">
<Project>{1c959542-bac2-4e55-9a6d-13251914cbb9}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\server\lib\server.vcxproj">
<Project>{18d09a24-8240-42d6-8cb6-236eee820262}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\tsf\tsf.vcxproj">
<Project>{2fd12fbb-1ddb-46d8-b818-1023c624caca}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\types\lib\types.vcxproj"> <ProjectReference Include="..\..\..\types\lib\types.vcxproj">
<Project>{18d09a24-8240-42d6-8cb6-236eee820263}</Project> <Project>{18d09a24-8240-42d6-8cb6-236eee820263}</Project>
</ProjectReference> </ProjectReference>
@ -40,6 +58,9 @@
<ProjectReference Include="..\lib\adapter.vcxproj"> <ProjectReference Include="..\lib\adapter.vcxproj">
<Project>{dcf55140-ef6a-4736-a403-957e4f7430bb}</Project> <Project>{dcf55140-ef6a-4736-a403-957e4f7430bb}</Project>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\..\..\buffer\out\lib\bufferout.vcxproj">
<Project>{0cf235bd-2da0-407e-90ee-c467e8bbc714}</Project>
</ProjectReference>
</ItemGroup> </ItemGroup>
<ItemDefinitionGroup> <ItemDefinitionGroup>
<ClCompile> <ClCompile>

View File

@ -9,6 +9,8 @@
#include "../../input/terminalInput.hpp" #include "../../input/terminalInput.hpp"
#include "../../../interactivity/inc/VtApiRedirection.hpp"
using namespace WEX::Common; using namespace WEX::Common;
using namespace WEX::Logging; using namespace WEX::Logging;
using namespace WEX::TestExecution; using namespace WEX::TestExecution;
@ -109,7 +111,7 @@ void InputTest::s_TerminalInputTestNullCallback(_In_ std::deque<std::unique_ptr<
irExpected.EventType = KEY_EVENT; irExpected.EventType = KEY_EVENT;
irExpected.Event.KeyEvent.bKeyDown = TRUE; irExpected.Event.KeyEvent.bKeyDown = TRUE;
irExpected.Event.KeyEvent.wRepeatCount = 1; irExpected.Event.KeyEvent.wRepeatCount = 1;
irExpected.Event.KeyEvent.wVirtualKeyCode = LOBYTE(VkKeyScanW(0)); irExpected.Event.KeyEvent.wVirtualKeyCode = LOBYTE(OneCoreSafeVkKeyScanW(0));
irExpected.Event.KeyEvent.dwControlKeyState = LEFT_CTRL_PRESSED; irExpected.Event.KeyEvent.dwControlKeyState = LEFT_CTRL_PRESSED;
irExpected.Event.KeyEvent.wVirtualScanCode = 0; irExpected.Event.KeyEvent.wVirtualScanCode = 0;
irExpected.Event.KeyEvent.uChar.UnicodeChar = L'\x0'; irExpected.Event.KeyEvent.uChar.UnicodeChar = L'\x0';
@ -165,7 +167,7 @@ void InputTest::TerminalInputTests()
irTest.Event.KeyEvent.wRepeatCount = 1; irTest.Event.KeyEvent.wRepeatCount = 1;
irTest.Event.KeyEvent.wVirtualKeyCode = vkey; irTest.Event.KeyEvent.wVirtualKeyCode = vkey;
irTest.Event.KeyEvent.bKeyDown = TRUE; irTest.Event.KeyEvent.bKeyDown = TRUE;
irTest.Event.KeyEvent.uChar.UnicodeChar = LOWORD(MapVirtualKeyW(vkey, MAPVK_VK_TO_CHAR)); irTest.Event.KeyEvent.uChar.UnicodeChar = LOWORD(OneCoreSafeMapVirtualKeyW(vkey, MAPVK_VK_TO_CHAR));
// Set up expected result // Set up expected result
switch (vkey) switch (vkey)
@ -376,8 +378,8 @@ void InputTest::TerminalInputModifierKeyTests()
VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"uiModifierKeystate", uiKeystate)); VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"uiModifierKeystate", uiKeystate));
const auto pInput = new TerminalInput(s_TerminalInputTestCallback); const auto pInput = new TerminalInput(s_TerminalInputTestCallback);
const auto slashVkey = LOBYTE(VkKeyScanW(L'/')); const auto slashVkey = LOBYTE(OneCoreSafeVkKeyScanW(L'/'));
const auto nullVkey = LOBYTE(VkKeyScanW(0)); const auto nullVkey = LOBYTE(OneCoreSafeVkKeyScanW(0));
Log::Comment(L"Sending every possible VKEY at the input stream for interception during key DOWN."); Log::Comment(L"Sending every possible VKEY at the input stream for interception during key DOWN.");
for (BYTE vkey = 0; vkey < BYTE_MAX; vkey++) for (BYTE vkey = 0; vkey < BYTE_MAX; vkey++)
@ -392,7 +394,7 @@ void InputTest::TerminalInputModifierKeyTests()
irTest.Event.KeyEvent.wRepeatCount = 1; irTest.Event.KeyEvent.wRepeatCount = 1;
irTest.Event.KeyEvent.wVirtualKeyCode = vkey; irTest.Event.KeyEvent.wVirtualKeyCode = vkey;
irTest.Event.KeyEvent.bKeyDown = TRUE; irTest.Event.KeyEvent.bKeyDown = TRUE;
irTest.Event.KeyEvent.uChar.UnicodeChar = LOWORD(MapVirtualKeyW(vkey, MAPVK_VK_TO_CHAR)); irTest.Event.KeyEvent.uChar.UnicodeChar = LOWORD(OneCoreSafeMapVirtualKeyW(vkey, MAPVK_VK_TO_CHAR));
if (ControlPressed(uiKeystate)) if (ControlPressed(uiKeystate))
{ {
@ -593,7 +595,7 @@ void InputTest::TerminalInputNullKeyTests()
Log::Comment(L"Sending every possible VKEY at the input stream for interception during key DOWN."); Log::Comment(L"Sending every possible VKEY at the input stream for interception during key DOWN.");
BYTE vkey = LOBYTE(VkKeyScanW(0)); BYTE vkey = LOBYTE(OneCoreSafeVkKeyScanW(0));
Log::Comment(NoThrowString().Format(L"Testing key, state =0x%x, 0x%x", vkey, uiKeystate)); Log::Comment(NoThrowString().Format(L"Testing key, state =0x%x, 0x%x", vkey, uiKeystate));
INPUT_RECORD irTest = { 0 }; INPUT_RECORD irTest = { 0 };
@ -699,7 +701,7 @@ void InputTest::DifferentModifiersTest()
// C-/ -> C-_ -> 0x1f // C-/ -> C-_ -> 0x1f
uiKeystate = LEFT_CTRL_PRESSED; uiKeystate = LEFT_CTRL_PRESSED;
vkey = LOBYTE(VkKeyScan(L'/')); vkey = LOBYTE(OneCoreSafeVkKeyScanW(L'/'));
s_expectedInput = L"\x1f"; s_expectedInput = L"\x1f";
TestKey(pInput, uiKeystate, vkey, L'/'); TestKey(pInput, uiKeystate, vkey, L'/');
uiKeystate = RIGHT_CTRL_PRESSED; uiKeystate = RIGHT_CTRL_PRESSED;
@ -707,7 +709,7 @@ void InputTest::DifferentModifiersTest()
// M-/ -> ESC / // M-/ -> ESC /
uiKeystate = LEFT_ALT_PRESSED; uiKeystate = LEFT_ALT_PRESSED;
vkey = LOBYTE(VkKeyScan(L'/')); vkey = LOBYTE(OneCoreSafeVkKeyScanW(L'/'));
s_expectedInput = L"\x1b/"; s_expectedInput = L"\x1b/";
TestKey(pInput, uiKeystate, vkey, L'/'); TestKey(pInput, uiKeystate, vkey, L'/');
uiKeystate = RIGHT_ALT_PRESSED; uiKeystate = RIGHT_ALT_PRESSED;
@ -717,7 +719,7 @@ void InputTest::DifferentModifiersTest()
// C-? -> DEL -> 0x7f // C-? -> DEL -> 0x7f
Log::Comment(NoThrowString().Format(L"Checking C-?")); Log::Comment(NoThrowString().Format(L"Checking C-?"));
// Use SHIFT_PRESSED to force us into differentiating between '/' and '?' // Use SHIFT_PRESSED to force us into differentiating between '/' and '?'
vkey = LOBYTE(VkKeyScan(L'?')); vkey = LOBYTE(OneCoreSafeVkKeyScanW(L'?'));
s_expectedInput = L"\x7f"; s_expectedInput = L"\x7f";
TestKey(pInput, SHIFT_PRESSED | LEFT_CTRL_PRESSED, vkey, L'?'); TestKey(pInput, SHIFT_PRESSED | LEFT_CTRL_PRESSED, vkey, L'?');
TestKey(pInput, SHIFT_PRESSED | RIGHT_CTRL_PRESSED, vkey, L'?'); TestKey(pInput, SHIFT_PRESSED | RIGHT_CTRL_PRESSED, vkey, L'?');
@ -725,7 +727,7 @@ void InputTest::DifferentModifiersTest()
// C-M-/ -> 0x1b0x1f // C-M-/ -> 0x1b0x1f
Log::Comment(NoThrowString().Format(L"Checking C-M-/")); Log::Comment(NoThrowString().Format(L"Checking C-M-/"));
uiKeystate = LEFT_CTRL_PRESSED | LEFT_ALT_PRESSED; uiKeystate = LEFT_CTRL_PRESSED | LEFT_ALT_PRESSED;
vkey = LOBYTE(VkKeyScan(L'/')); vkey = LOBYTE(OneCoreSafeVkKeyScanW(L'/'));
s_expectedInput = L"\x1b\x1f"; s_expectedInput = L"\x1b\x1f";
TestKey(pInput, LEFT_CTRL_PRESSED | LEFT_ALT_PRESSED, vkey, L'/'); TestKey(pInput, LEFT_CTRL_PRESSED | LEFT_ALT_PRESSED, vkey, L'/');
TestKey(pInput, RIGHT_CTRL_PRESSED | LEFT_ALT_PRESSED, vkey, L'/'); TestKey(pInput, RIGHT_CTRL_PRESSED | LEFT_ALT_PRESSED, vkey, L'/');
@ -735,7 +737,7 @@ void InputTest::DifferentModifiersTest()
// C-M-? -> 0x1b0x7f // C-M-? -> 0x1b0x7f
Log::Comment(NoThrowString().Format(L"Checking C-M-?")); Log::Comment(NoThrowString().Format(L"Checking C-M-?"));
uiKeystate = LEFT_CTRL_PRESSED | LEFT_ALT_PRESSED; uiKeystate = LEFT_CTRL_PRESSED | LEFT_ALT_PRESSED;
vkey = LOBYTE(VkKeyScan(L'?')); vkey = LOBYTE(OneCoreSafeVkKeyScanW(L'?'));
s_expectedInput = L"\x1b\x7f"; s_expectedInput = L"\x1b\x7f";
TestKey(pInput, SHIFT_PRESSED | LEFT_CTRL_PRESSED | LEFT_ALT_PRESSED, vkey, L'?'); TestKey(pInput, SHIFT_PRESSED | LEFT_CTRL_PRESSED | LEFT_ALT_PRESSED, vkey, L'?');
TestKey(pInput, SHIFT_PRESSED | RIGHT_CTRL_PRESSED | LEFT_ALT_PRESSED, vkey, L'?'); TestKey(pInput, SHIFT_PRESSED | RIGHT_CTRL_PRESSED | LEFT_ALT_PRESSED, vkey, L'?');

View File

@ -5,6 +5,7 @@
#include <windows.h> #include <windows.h>
#include "terminalInput.hpp" #include "terminalInput.hpp"
#include "../types/inc/utils.hpp" #include "../types/inc/utils.hpp"
#include "../../interactivity/inc/VtApiRedirection.hpp"
using namespace Microsoft::Console::VirtualTerminal; using namespace Microsoft::Console::VirtualTerminal;

View File

@ -12,7 +12,7 @@
# Preprocessor Settings # Preprocessor Settings
# ------------------------------------- # -------------------------------------
C_DEFINES = $(C_DEFINES) -DBUILD_ONECORE_INTERACTIVITY C_DEFINES = $(C_DEFINES)
# ------------------------------------- # -------------------------------------
# Build System Settings # Build System Settings

View File

@ -10,6 +10,7 @@
#define WIL_SUPPORT_BITOPERATION_PASCAL_NAMES #define WIL_SUPPORT_BITOPERATION_PASCAL_NAMES
#include <wil/Common.h> #include <wil/Common.h>
#include "../../interactivity/inc/VtApiRedirection.hpp"
#include "../../inc/unicode.hpp" #include "../../inc/unicode.hpp"
#include "../../types/inc/Utf16Parser.hpp" #include "../../types/inc/Utf16Parser.hpp"
@ -428,8 +429,8 @@ static bool _searchWithModifier(const KeyEvent& keyEvent, InputSender sender)
// VkKeyScan will give us both the Vkey of the key needed for this // VkKeyScan will give us both the Vkey of the key needed for this
// character, and the modifiers the user might need to press to get // character, and the modifiers the user might need to press to get
// this character. // this character.
const auto slashKeyScan = VkKeyScan(L'/'); // On USASCII: 0x00bf const auto slashKeyScan = OneCoreSafeVkKeyScanW(L'/'); // On USASCII: 0x00bf
const auto questionMarkKeyScan = VkKeyScan(L'?'); //On USASCII: 0x01bf const auto questionMarkKeyScan = OneCoreSafeVkKeyScanW(L'?'); //On USASCII: 0x01bf
const auto slashVkey = LOBYTE(slashKeyScan); const auto slashVkey = LOBYTE(slashKeyScan);
const auto questionMarkVkey = LOBYTE(questionMarkKeyScan); const auto questionMarkVkey = LOBYTE(questionMarkKeyScan);
@ -606,7 +607,7 @@ bool TerminalInput::HandleKey(const IInputEvent* const pInEvent)
// Currently, when we're called with Alt+Ctrl+@, ch will be 0, since Ctrl+@ equals a null byte. // Currently, when we're called with Alt+Ctrl+@, ch will be 0, since Ctrl+@ equals a null byte.
// VkKeyScanW(0) in turn returns the vkey for the null character (ASCII @). // VkKeyScanW(0) in turn returns the vkey for the null character (ASCII @).
// -> Use the vkey to determine if Ctrl+@ is being pressed and produce ^[^@. // -> Use the vkey to determine if Ctrl+@ is being pressed and produce ^[^@.
if (ch == UNICODE_NULL && vkey == LOBYTE(VkKeyScanW(0))) if (ch == UNICODE_NULL && vkey == LOBYTE(OneCoreSafeVkKeyScanW(0)))
{ {
_SendEscapedInputSequence(L'\0'); _SendEscapedInputSequence(L'\0');
return true; return true;
@ -647,7 +648,7 @@ bool TerminalInput::HandleKey(const IInputEvent* const pInEvent)
// Currently, when we're called with Ctrl+@, ch will be 0, since Ctrl+@ equals a null byte. // Currently, when we're called with Ctrl+@, ch will be 0, since Ctrl+@ equals a null byte.
// VkKeyScanW(0) in turn returns the vkey for the null character (ASCII @). // VkKeyScanW(0) in turn returns the vkey for the null character (ASCII @).
// -> Use the vkey to alternatively determine if Ctrl+@ is being pressed. // -> Use the vkey to alternatively determine if Ctrl+@ is being pressed.
if (ch == UNICODE_SPACE || (ch == UNICODE_NULL && vkey == LOBYTE(VkKeyScanW(0)))) if (ch == UNICODE_SPACE || (ch == UNICODE_NULL && vkey == LOBYTE(OneCoreSafeVkKeyScanW(0))))
{ {
_SendNullInputSequence(keyEvent.GetActiveModifierKeys()); _SendNullInputSequence(keyEvent.GetActiveModifierKeys());
return true; return true;
@ -659,7 +660,7 @@ bool TerminalInput::HandleKey(const IInputEvent* const pInEvent)
if (ch == UNICODE_NULL) if (ch == UNICODE_NULL)
{ {
// -> Try to infer the character from the vkey. // -> Try to infer the character from the vkey.
auto mappedChar = LOWORD(MapVirtualKeyW(keyEvent.GetVirtualKeyCode(), MAPVK_VK_TO_CHAR)); auto mappedChar = LOWORD(OneCoreSafeMapVirtualKeyW(keyEvent.GetVirtualKeyCode(), MAPVK_VK_TO_CHAR));
if (mappedChar) if (mappedChar)
{ {
// Pressing the control key causes all bits but the 5 least // Pressing the control key causes all bits but the 5 least
@ -760,7 +761,7 @@ void TerminalInput::_SendNullInputSequence(const DWORD controlKeyState) const
std::deque<std::unique_ptr<IInputEvent>> inputEvents; std::deque<std::unique_ptr<IInputEvent>> inputEvents;
inputEvents.push_back(std::make_unique<KeyEvent>(true, inputEvents.push_back(std::make_unique<KeyEvent>(true,
1ui16, 1ui16,
LOBYTE(VkKeyScanW(0)), LOBYTE(OneCoreSafeVkKeyScanW(0)),
0ui16, 0ui16,
L'\x0', L'\x0',
controlKeyState)); controlKeyState));

View File

@ -8,6 +8,7 @@
#include "../../inc/unicode.hpp" #include "../../inc/unicode.hpp"
#include "ascii.hpp" #include "ascii.hpp"
#include "../../interactivity/inc/VtApiRedirection.hpp"
using namespace Microsoft::Console::VirtualTerminal; using namespace Microsoft::Console::VirtualTerminal;
@ -581,7 +582,7 @@ void InputStateMachineEngine::_GenerateWrappedSequence(const wchar_t wch,
next.Event.KeyEvent.dwControlKeyState = currentModifiers; next.Event.KeyEvent.dwControlKeyState = currentModifiers;
next.Event.KeyEvent.wRepeatCount = 1; next.Event.KeyEvent.wRepeatCount = 1;
next.Event.KeyEvent.wVirtualKeyCode = VK_SHIFT; next.Event.KeyEvent.wVirtualKeyCode = VK_SHIFT;
next.Event.KeyEvent.wVirtualScanCode = gsl::narrow_cast<WORD>(MapVirtualKey(VK_SHIFT, MAPVK_VK_TO_VSC)); next.Event.KeyEvent.wVirtualScanCode = gsl::narrow_cast<WORD>(OneCoreSafeMapVirtualKeyW(VK_SHIFT, MAPVK_VK_TO_VSC));
next.Event.KeyEvent.uChar.UnicodeChar = 0x0; next.Event.KeyEvent.uChar.UnicodeChar = 0x0;
input.push_back(next); input.push_back(next);
} }
@ -593,7 +594,7 @@ void InputStateMachineEngine::_GenerateWrappedSequence(const wchar_t wch,
next.Event.KeyEvent.dwControlKeyState = currentModifiers; next.Event.KeyEvent.dwControlKeyState = currentModifiers;
next.Event.KeyEvent.wRepeatCount = 1; next.Event.KeyEvent.wRepeatCount = 1;
next.Event.KeyEvent.wVirtualKeyCode = VK_MENU; next.Event.KeyEvent.wVirtualKeyCode = VK_MENU;
next.Event.KeyEvent.wVirtualScanCode = gsl::narrow_cast<WORD>(MapVirtualKey(VK_MENU, MAPVK_VK_TO_VSC)); next.Event.KeyEvent.wVirtualScanCode = gsl::narrow_cast<WORD>(OneCoreSafeMapVirtualKeyW(VK_MENU, MAPVK_VK_TO_VSC));
next.Event.KeyEvent.uChar.UnicodeChar = 0x0; next.Event.KeyEvent.uChar.UnicodeChar = 0x0;
input.push_back(next); input.push_back(next);
} }
@ -605,7 +606,7 @@ void InputStateMachineEngine::_GenerateWrappedSequence(const wchar_t wch,
next.Event.KeyEvent.dwControlKeyState = currentModifiers; next.Event.KeyEvent.dwControlKeyState = currentModifiers;
next.Event.KeyEvent.wRepeatCount = 1; next.Event.KeyEvent.wRepeatCount = 1;
next.Event.KeyEvent.wVirtualKeyCode = VK_CONTROL; next.Event.KeyEvent.wVirtualKeyCode = VK_CONTROL;
next.Event.KeyEvent.wVirtualScanCode = gsl::narrow_cast<WORD>(MapVirtualKey(VK_CONTROL, MAPVK_VK_TO_VSC)); next.Event.KeyEvent.wVirtualScanCode = gsl::narrow_cast<WORD>(OneCoreSafeMapVirtualKeyW(VK_CONTROL, MAPVK_VK_TO_VSC));
next.Event.KeyEvent.uChar.UnicodeChar = 0x0; next.Event.KeyEvent.uChar.UnicodeChar = 0x0;
input.push_back(next); input.push_back(next);
} }
@ -623,7 +624,7 @@ void InputStateMachineEngine::_GenerateWrappedSequence(const wchar_t wch,
next.Event.KeyEvent.dwControlKeyState = currentModifiers; next.Event.KeyEvent.dwControlKeyState = currentModifiers;
next.Event.KeyEvent.wRepeatCount = 1; next.Event.KeyEvent.wRepeatCount = 1;
next.Event.KeyEvent.wVirtualKeyCode = VK_CONTROL; next.Event.KeyEvent.wVirtualKeyCode = VK_CONTROL;
next.Event.KeyEvent.wVirtualScanCode = gsl::narrow_cast<WORD>(MapVirtualKey(VK_CONTROL, MAPVK_VK_TO_VSC)); next.Event.KeyEvent.wVirtualScanCode = gsl::narrow_cast<WORD>(OneCoreSafeMapVirtualKeyW(VK_CONTROL, MAPVK_VK_TO_VSC));
next.Event.KeyEvent.uChar.UnicodeChar = 0x0; next.Event.KeyEvent.uChar.UnicodeChar = 0x0;
input.push_back(next); input.push_back(next);
} }
@ -635,7 +636,7 @@ void InputStateMachineEngine::_GenerateWrappedSequence(const wchar_t wch,
next.Event.KeyEvent.dwControlKeyState = currentModifiers; next.Event.KeyEvent.dwControlKeyState = currentModifiers;
next.Event.KeyEvent.wRepeatCount = 1; next.Event.KeyEvent.wRepeatCount = 1;
next.Event.KeyEvent.wVirtualKeyCode = VK_MENU; next.Event.KeyEvent.wVirtualKeyCode = VK_MENU;
next.Event.KeyEvent.wVirtualScanCode = gsl::narrow_cast<WORD>(MapVirtualKey(VK_MENU, MAPVK_VK_TO_VSC)); next.Event.KeyEvent.wVirtualScanCode = gsl::narrow_cast<WORD>(OneCoreSafeMapVirtualKeyW(VK_MENU, MAPVK_VK_TO_VSC));
next.Event.KeyEvent.uChar.UnicodeChar = 0x0; next.Event.KeyEvent.uChar.UnicodeChar = 0x0;
input.push_back(next); input.push_back(next);
} }
@ -647,7 +648,7 @@ void InputStateMachineEngine::_GenerateWrappedSequence(const wchar_t wch,
next.Event.KeyEvent.dwControlKeyState = currentModifiers; next.Event.KeyEvent.dwControlKeyState = currentModifiers;
next.Event.KeyEvent.wRepeatCount = 1; next.Event.KeyEvent.wRepeatCount = 1;
next.Event.KeyEvent.wVirtualKeyCode = VK_SHIFT; next.Event.KeyEvent.wVirtualKeyCode = VK_SHIFT;
next.Event.KeyEvent.wVirtualScanCode = gsl::narrow_cast<WORD>(MapVirtualKey(VK_SHIFT, MAPVK_VK_TO_VSC)); next.Event.KeyEvent.wVirtualScanCode = gsl::narrow_cast<WORD>(OneCoreSafeMapVirtualKeyW(VK_SHIFT, MAPVK_VK_TO_VSC));
next.Event.KeyEvent.uChar.UnicodeChar = 0x0; next.Event.KeyEvent.uChar.UnicodeChar = 0x0;
input.push_back(next); input.push_back(next);
} }
@ -678,7 +679,7 @@ void InputStateMachineEngine::_GetSingleKeypress(const wchar_t wch,
rec.Event.KeyEvent.dwControlKeyState = modifierState; rec.Event.KeyEvent.dwControlKeyState = modifierState;
rec.Event.KeyEvent.wRepeatCount = 1; rec.Event.KeyEvent.wRepeatCount = 1;
rec.Event.KeyEvent.wVirtualKeyCode = vkey; rec.Event.KeyEvent.wVirtualKeyCode = vkey;
rec.Event.KeyEvent.wVirtualScanCode = gsl::narrow_cast<WORD>(MapVirtualKey(vkey, MAPVK_VK_TO_VSC)); rec.Event.KeyEvent.wVirtualScanCode = gsl::narrow_cast<WORD>(OneCoreSafeMapVirtualKeyW(vkey, MAPVK_VK_TO_VSC));
rec.Event.KeyEvent.uChar.UnicodeChar = wch; rec.Event.KeyEvent.uChar.UnicodeChar = wch;
input.push_back(rec); input.push_back(rec);
@ -717,7 +718,7 @@ bool InputStateMachineEngine::_WriteSingleKey(const wchar_t wch, const short vke
// - true iff we successfully wrote the keypress to the input callback. // - true iff we successfully wrote the keypress to the input callback.
bool InputStateMachineEngine::_WriteSingleKey(const short vkey, const DWORD modifierState) bool InputStateMachineEngine::_WriteSingleKey(const short vkey, const DWORD modifierState)
{ {
const auto wch = gsl::narrow_cast<wchar_t>(MapVirtualKey(vkey, MAPVK_VK_TO_CHAR)); const auto wch = gsl::narrow_cast<wchar_t>(OneCoreSafeMapVirtualKeyW(vkey, MAPVK_VK_TO_CHAR));
return _WriteSingleKey(wch, vkey, modifierState); return _WriteSingleKey(wch, vkey, modifierState);
} }
@ -1045,7 +1046,7 @@ bool InputStateMachineEngine::_GenerateKeyFromChar(const wchar_t wch,
DWORD& modifierState) noexcept DWORD& modifierState) noexcept
{ {
// Low order byte is key, high order is modifiers // Low order byte is key, high order is modifiers
const auto keyscan = VkKeyScanW(wch); const auto keyscan = OneCoreSafeVkKeyScanW(wch);
short key = LOBYTE(keyscan); short key = LOBYTE(keyscan);

View File

@ -14,7 +14,7 @@
# Preprocessor Settings # Preprocessor Settings
# ------------------------------------- # -------------------------------------
C_DEFINES = $(C_DEFINES) -DBUILD_ONECORE_INTERACTIVITY C_DEFINES = $(C_DEFINES)
# ------------------------------------- # -------------------------------------
# Build System Settings # Build System Settings

View File

@ -18,6 +18,8 @@
#include <string> #include <string>
#include <algorithm> #include <algorithm>
#include "../../../interactivity/inc/VtApiRedirection.hpp"
using namespace WEX::Common; using namespace WEX::Common;
using namespace WEX::Logging; using namespace WEX::Logging;
using namespace WEX::TestExecution; using namespace WEX::TestExecution;
@ -443,10 +445,10 @@ void InputEngineTest::C0Test()
break; break;
} }
auto keyscan = VkKeyScanW(expectedWch); auto keyscan = OneCoreSafeVkKeyScanW(expectedWch);
short vkey = keyscan & 0xff; short vkey = keyscan & 0xff;
short keyscanModifiers = (keyscan >> 8) & 0xff; short keyscanModifiers = (keyscan >> 8) & 0xff;
auto scanCode = (WORD)MapVirtualKeyW(vkey, MAPVK_VK_TO_VSC); auto scanCode = (WORD)OneCoreSafeMapVirtualKeyW(vkey, MAPVK_VK_TO_VSC);
DWORD dwModifierState = 0; DWORD dwModifierState = 0;
if (writeCtrl) if (writeCtrl)
@ -521,9 +523,9 @@ void InputEngineTest::AlphanumericTest()
{ {
auto inputSeq = std::wstring(&wch, 1); auto inputSeq = std::wstring(&wch, 1);
auto keyscan = VkKeyScanW(wch); auto keyscan = OneCoreSafeVkKeyScanW(wch);
short vkey = keyscan & 0xff; short vkey = keyscan & 0xff;
WORD scanCode = (wchar_t)MapVirtualKeyW(vkey, MAPVK_VK_TO_VSC); WORD scanCode = (wchar_t)OneCoreSafeMapVirtualKeyW(vkey, MAPVK_VK_TO_VSC);
short keyscanModifiers = (keyscan >> 8) & 0xff; short keyscanModifiers = (keyscan >> 8) & 0xff;
// Because of course, these are not the same flags. // Because of course, these are not the same flags.
@ -574,8 +576,8 @@ void InputEngineTest::RoundTripTest()
for (BYTE vkey = 0; vkey < BYTE_MAX; vkey++) for (BYTE vkey = 0; vkey < BYTE_MAX; vkey++)
{ {
wchar_t wch = (wchar_t)MapVirtualKeyW(vkey, MAPVK_VK_TO_CHAR); wchar_t wch = (wchar_t)OneCoreSafeMapVirtualKeyW(vkey, MAPVK_VK_TO_CHAR);
WORD scanCode = (wchar_t)MapVirtualKeyW(vkey, MAPVK_VK_TO_VSC); WORD scanCode = (wchar_t)OneCoreSafeMapVirtualKeyW(vkey, MAPVK_VK_TO_VSC);
unsigned int uiActualKeystate = 0; unsigned int uiActualKeystate = 0;
@ -761,7 +763,7 @@ void InputEngineTest::CursorPositioningTest()
inputRec.Event.KeyEvent.dwControlKeyState = LEFT_ALT_PRESSED | SHIFT_PRESSED; inputRec.Event.KeyEvent.dwControlKeyState = LEFT_ALT_PRESSED | SHIFT_PRESSED;
inputRec.Event.KeyEvent.wRepeatCount = 1; inputRec.Event.KeyEvent.wRepeatCount = 1;
inputRec.Event.KeyEvent.wVirtualKeyCode = VK_F3; inputRec.Event.KeyEvent.wVirtualKeyCode = VK_F3;
inputRec.Event.KeyEvent.wVirtualScanCode = static_cast<WORD>(MapVirtualKey(VK_F3, MAPVK_VK_TO_VSC)); inputRec.Event.KeyEvent.wVirtualScanCode = static_cast<WORD>(OneCoreSafeMapVirtualKeyW(VK_F3, MAPVK_VK_TO_VSC));
inputRec.Event.KeyEvent.uChar.UnicodeChar = L'\0'; inputRec.Event.KeyEvent.uChar.UnicodeChar = L'\0';
testState.vExpectedInput.push_back(inputRec); testState.vExpectedInput.push_back(inputRec);
@ -787,7 +789,7 @@ void InputEngineTest::CSICursorBackTabTest()
inputRec.Event.KeyEvent.dwControlKeyState = SHIFT_PRESSED; inputRec.Event.KeyEvent.dwControlKeyState = SHIFT_PRESSED;
inputRec.Event.KeyEvent.wRepeatCount = 1; inputRec.Event.KeyEvent.wRepeatCount = 1;
inputRec.Event.KeyEvent.wVirtualKeyCode = VK_TAB; inputRec.Event.KeyEvent.wVirtualKeyCode = VK_TAB;
inputRec.Event.KeyEvent.wVirtualScanCode = static_cast<WORD>(MapVirtualKeyW(VK_TAB, MAPVK_VK_TO_VSC)); inputRec.Event.KeyEvent.wVirtualScanCode = static_cast<WORD>(OneCoreSafeMapVirtualKeyW(VK_TAB, MAPVK_VK_TO_VSC));
inputRec.Event.KeyEvent.uChar.UnicodeChar = L'\t'; inputRec.Event.KeyEvent.uChar.UnicodeChar = L'\t';
testState.vExpectedInput.push_back(inputRec); testState.vExpectedInput.push_back(inputRec);
@ -829,8 +831,8 @@ void InputEngineTest::EnhancedKeysTest()
{ {
INPUT_RECORD inputRec; INPUT_RECORD inputRec;
const auto wch = (wchar_t)MapVirtualKeyW(vkey, MAPVK_VK_TO_CHAR); const auto wch = (wchar_t)OneCoreSafeMapVirtualKeyW(vkey, MAPVK_VK_TO_CHAR);
const auto scanCode = (WORD)MapVirtualKeyW(vkey, MAPVK_VK_TO_VSC); const auto scanCode = (WORD)OneCoreSafeMapVirtualKeyW(vkey, MAPVK_VK_TO_VSC);
inputRec.EventType = KEY_EVENT; inputRec.EventType = KEY_EVENT;
inputRec.Event.KeyEvent.bKeyDown = TRUE; inputRec.Event.KeyEvent.bKeyDown = TRUE;
@ -873,8 +875,8 @@ void InputEngineTest::SS3CursorKeyTest()
{ {
INPUT_RECORD inputRec; INPUT_RECORD inputRec;
const auto wch = (wchar_t)MapVirtualKeyW(vkey, MAPVK_VK_TO_CHAR); const auto wch = (wchar_t)OneCoreSafeMapVirtualKeyW(vkey, MAPVK_VK_TO_CHAR);
const auto scanCode = (WORD)MapVirtualKeyW(vkey, MAPVK_VK_TO_VSC); const auto scanCode = (WORD)OneCoreSafeMapVirtualKeyW(vkey, MAPVK_VK_TO_VSC);
inputRec.EventType = KEY_EVENT; inputRec.EventType = KEY_EVENT;
inputRec.Event.KeyEvent.bKeyDown = TRUE; inputRec.Event.KeyEvent.bKeyDown = TRUE;
@ -909,7 +911,7 @@ void InputEngineTest::AltBackspaceTest()
inputRec.Event.KeyEvent.dwControlKeyState = LEFT_ALT_PRESSED; inputRec.Event.KeyEvent.dwControlKeyState = LEFT_ALT_PRESSED;
inputRec.Event.KeyEvent.wRepeatCount = 1; inputRec.Event.KeyEvent.wRepeatCount = 1;
inputRec.Event.KeyEvent.wVirtualKeyCode = VK_BACK; inputRec.Event.KeyEvent.wVirtualKeyCode = VK_BACK;
inputRec.Event.KeyEvent.wVirtualScanCode = static_cast<WORD>(MapVirtualKeyW(VK_BACK, MAPVK_VK_TO_VSC)); inputRec.Event.KeyEvent.wVirtualScanCode = static_cast<WORD>(OneCoreSafeMapVirtualKeyW(VK_BACK, MAPVK_VK_TO_VSC));
inputRec.Event.KeyEvent.uChar.UnicodeChar = L'\x08'; inputRec.Event.KeyEvent.uChar.UnicodeChar = L'\x08';
testState.vExpectedInput.push_back(inputRec); testState.vExpectedInput.push_back(inputRec);
@ -937,7 +939,7 @@ void InputEngineTest::AltCtrlDTest()
inputRec.Event.KeyEvent.dwControlKeyState = LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED; inputRec.Event.KeyEvent.dwControlKeyState = LEFT_ALT_PRESSED | LEFT_CTRL_PRESSED;
inputRec.Event.KeyEvent.wRepeatCount = 1; inputRec.Event.KeyEvent.wRepeatCount = 1;
inputRec.Event.KeyEvent.wVirtualKeyCode = 0x44; // D key inputRec.Event.KeyEvent.wVirtualKeyCode = 0x44; // D key
inputRec.Event.KeyEvent.wVirtualScanCode = static_cast<WORD>(MapVirtualKeyW(0x44, MAPVK_VK_TO_VSC)); inputRec.Event.KeyEvent.wVirtualScanCode = static_cast<WORD>(OneCoreSafeMapVirtualKeyW(0x44, MAPVK_VK_TO_VSC));
inputRec.Event.KeyEvent.uChar.UnicodeChar = L'\x04'; inputRec.Event.KeyEvent.uChar.UnicodeChar = L'\x04';
testState.vExpectedInput.push_back(inputRec); testState.vExpectedInput.push_back(inputRec);
@ -1032,7 +1034,7 @@ void InputEngineTest::AltBackspaceEnterTest()
inputRec.Event.KeyEvent.dwControlKeyState = LEFT_ALT_PRESSED; inputRec.Event.KeyEvent.dwControlKeyState = LEFT_ALT_PRESSED;
inputRec.Event.KeyEvent.wRepeatCount = 1; inputRec.Event.KeyEvent.wRepeatCount = 1;
inputRec.Event.KeyEvent.wVirtualKeyCode = VK_BACK; inputRec.Event.KeyEvent.wVirtualKeyCode = VK_BACK;
inputRec.Event.KeyEvent.wVirtualScanCode = static_cast<WORD>(MapVirtualKeyW(VK_BACK, MAPVK_VK_TO_VSC)); inputRec.Event.KeyEvent.wVirtualScanCode = static_cast<WORD>(OneCoreSafeMapVirtualKeyW(VK_BACK, MAPVK_VK_TO_VSC));
inputRec.Event.KeyEvent.uChar.UnicodeChar = L'\x08'; inputRec.Event.KeyEvent.uChar.UnicodeChar = L'\x08';
// First, expect a alt+backspace. // First, expect a alt+backspace.
@ -1047,7 +1049,7 @@ void InputEngineTest::AltBackspaceEnterTest()
inputRec.Event.KeyEvent.wVirtualKeyCode = VK_RETURN; inputRec.Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
inputRec.Event.KeyEvent.dwControlKeyState = 0; inputRec.Event.KeyEvent.dwControlKeyState = 0;
inputRec.Event.KeyEvent.wVirtualScanCode = static_cast<WORD>(MapVirtualKeyW(VK_RETURN, MAPVK_VK_TO_VSC)); inputRec.Event.KeyEvent.wVirtualScanCode = static_cast<WORD>(OneCoreSafeMapVirtualKeyW(VK_RETURN, MAPVK_VK_TO_VSC));
inputRec.Event.KeyEvent.uChar.UnicodeChar = L'\x0d'; //maybe \xa inputRec.Event.KeyEvent.uChar.UnicodeChar = L'\x0d'; //maybe \xa
// Then, expect a enter // Then, expect a enter
@ -1350,9 +1352,9 @@ void InputEngineTest::CtrlAltZCtrlAltXTest()
auto inputSeq = L"\x1b\x1a"; // ^[^Z auto inputSeq = L"\x1b\x1a"; // ^[^Z
auto expectedWch = L'Z'; auto expectedWch = L'Z';
auto keyscan = VkKeyScanW(expectedWch); auto keyscan = OneCoreSafeVkKeyScanW(expectedWch);
short vkey = keyscan & 0xff; short vkey = keyscan & 0xff;
auto scanCode = (WORD)MapVirtualKeyW(vkey, MAPVK_VK_TO_VSC); auto scanCode = (WORD)OneCoreSafeMapVirtualKeyW(vkey, MAPVK_VK_TO_VSC);
INPUT_RECORD inputRec; INPUT_RECORD inputRec;
@ -1372,9 +1374,9 @@ void InputEngineTest::CtrlAltZCtrlAltXTest()
auto inputSeq = L"\x1b\x18"; // ^[^X auto inputSeq = L"\x1b\x18"; // ^[^X
auto expectedWch = L'X'; auto expectedWch = L'X';
auto keyscan = VkKeyScanW(expectedWch); auto keyscan = OneCoreSafeVkKeyScanW(expectedWch);
short vkey = keyscan & 0xff; short vkey = keyscan & 0xff;
auto scanCode = (WORD)MapVirtualKeyW(vkey, MAPVK_VK_TO_VSC); auto scanCode = (WORD)OneCoreSafeMapVirtualKeyW(vkey, MAPVK_VK_TO_VSC);
INPUT_RECORD inputRec; INPUT_RECORD inputRec;

View File

@ -13,7 +13,7 @@ DLLDEF =
# Preprocessor Settings # Preprocessor Settings
# ------------------------------------- # -------------------------------------
C_DEFINES = $(C_DEFINES) -DBUILD_ONECORE_INTERACTIVITY C_DEFINES = $(C_DEFINES)
# ------------------------------------- # -------------------------------------
# Sources, Headers, and Libraries # Sources, Headers, and Libraries
@ -31,16 +31,107 @@ TARGETLIBS = \
$(ONECORE_INTERNAL_SDK_LIB_PATH)\onecoreuuid.lib \ $(ONECORE_INTERNAL_SDK_LIB_PATH)\onecoreuuid.lib \
$(ONECOREUAP_INTERNAL_SDK_LIB_PATH)\onecoreuapuuid.lib \ $(ONECOREUAP_INTERNAL_SDK_LIB_PATH)\onecoreuapuuid.lib \
$(ONECORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\onecore_internal.lib \ $(ONECORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\onecore_internal.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-mouse-l1.lib \ $(ONECOREUAP_EXTERNAL_SDK_LIB_PATH)\propsys.lib \
$(CONSOLE_OBJ_PATH)\terminal\parser\lib\$(O)\ConTermParser.lib \ $(ONECOREUAP_EXTERNAL_SDK_LIB_PATH)\d2d1.lib \
$(ONECOREUAP_EXTERNAL_SDK_LIB_PATH)\dwrite.lib \
$(ONECOREUAP_EXTERNAL_SDK_LIB_PATH)\dxgi.lib \
$(ONECOREUAP_EXTERNAL_SDK_LIB_PATH)\d3d11.lib \
$(ONECOREUAP_EXTERNAL_SDK_LIB_PATH)\d3dcompiler.lib \
$(MODERNCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\api-ms-win-mm-playsound-l1.lib \
$(ONECORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-dwmapi-ext-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-edputil-policy-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-gdi-dc-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-gdi-dc-create-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-gdi-draw-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-gdi-font-l1.lib \
$(ONECOREWINDOWS_INTERNAL_LIB_PATH_L)\ext-ms-win-gdi-internal-desktop-l1-1-0.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-caret-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-dialogbox-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-draw-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-gui-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-menu-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-misc-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-mouse-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-rectangle-ext-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-server-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-ntuser-window-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-gdi-object-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-gdi-rgn-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-cursor-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-dc-access-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-rawinput-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-sysparams-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-window-ext-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-rtcore-ntuser-winstamin-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-shell-shell32-l1.lib \
$(MINCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-uxtheme-themes-l1.lib \
$(ONECORESHELL_INTERNAL_LIB_VPATH_L)\api-ms-win-shell-dataobject-l1.lib \
$(ONECORESHELL_INTERNAL_LIB_VPATH_L)\api-ms-win-shell-namespace-l1.lib \
$(MODERNCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-uiacore-l1.lib \
$(MODERNCORE_INTERNAL_PRIV_SDK_LIB_VPATH_L)\ext-ms-win-usp10-l1.lib \
$(WINCORE_OBJ_PATH)\console\conint\$(O)\conint.lib \
$(CONSOLE_OBJ_PATH)\buffer\out\lib\$(O)\conbufferout.lib \
$(CONSOLE_OBJ_PATH)\host\lib\$(O)\conhostv2.lib \
$(CONSOLE_OBJ_PATH)\tsf\$(O)\contsf.lib \
$(CONSOLE_OBJ_PATH)\propslib\$(O)\conprops.lib \
$(CONSOLE_OBJ_PATH)\terminal\input\lib\$(O)\ConTermInput.lib \ $(CONSOLE_OBJ_PATH)\terminal\input\lib\$(O)\ConTermInput.lib \
$(CONSOLE_OBJ_PATH)\terminal\adapter\lib\$(O)\ConTermAdapter.lib \
$(CONSOLE_OBJ_PATH)\terminal\parser\lib\$(O)\ConTermParser.lib \
$(CONSOLE_OBJ_PATH)\renderer\base\lib\$(O)\ConRenderBase.lib \
$(CONSOLE_OBJ_PATH)\renderer\gdi\lib\$(O)\ConRenderGdi.lib \
$(CONSOLE_OBJ_PATH)\renderer\wddmcon\lib\$(O)\ConRenderWddmCon.lib \
$(CONSOLE_OBJ_PATH)\renderer\vt\lib\$(O)\ConRenderVt.lib \
$(CONSOLE_OBJ_PATH)\audio\midi\lib\$(O)\ConAudioMidi.lib \
$(CONSOLE_OBJ_PATH)\server\lib\$(O)\ConServer.lib \
$(CONSOLE_OBJ_PATH)\interactivity\base\lib\$(O)\ConInteractivityBaseLib.lib \ $(CONSOLE_OBJ_PATH)\interactivity\base\lib\$(O)\ConInteractivityBaseLib.lib \
$(CONSOLE_OBJ_PATH)\interactivity\win32\lib\$(O)\ConInteractivityWin32Lib.lib \
$(CONSOLE_OBJ_PATH)\interactivity\onecore\lib\$(O)\ConInteractivityOneCoreLib.lib \
$(CONSOLE_OBJ_PATH)\types\lib\$(O)\ConTypes.lib \ $(CONSOLE_OBJ_PATH)\types\lib\$(O)\ConTypes.lib \
DELAYLOAD = \ DELAYLOAD = \
PROPSYS.dll; \
D2D1.dll; \
DWrite.dll; \
DXGI.dll; \
D3D11.dll; \
OLEAUT32.dll; \
api-ms-win-mm-playsound-l1.dll; \
api-ms-win-shcore-scaling-l1.dll; \
api-ms-win-shell-dataobject-l1.dll; \
api-ms-win-shell-namespace-l1.dll; \
ext-ms-win-dwmapi-ext-l1.dll; \
ext-ms-win-edputil-policy-l1.dll; \
ext-ms-win-gdi-dc-l1.dll; \
ext-ms-win-gdi-dc-create-l1.dll; \
ext-ms-win-gdi-draw-l1.dll; \
ext-ms-win-gdi-font-l1.dll; \
ext-ms-win-gdi-internal-desktop-l1.dll; \
ext-ms-win-ntuser-caret-l1.dll; \
ext-ms-win-ntuser-dialogbox-l1.dll; \
ext-ms-win-ntuser-draw-l1.dll; \
ext-ms-win-ntuser-keyboard-l1.dll; \ ext-ms-win-ntuser-keyboard-l1.dll; \
ext-ms-win-rtcore-ntuser-mouse-l1.dll; \ ext-ms-win-ntuser-gui-l1.dll; \
ext-ms-win-ntuser-menu-l1.dll; \
ext-ms-win-ntuser-message-l1.dll; \
ext-ms-win-ntuser-misc-l1.dll; \
ext-ms-win-ntuser-mouse-l1.dll; \
ext-ms-win-ntuser-rectangle-ext-l1.dll; \
ext-ms-win-ntuser-server-l1.dll; \
ext-ms-win-ntuser-sysparams-ext-l1.dll; \
ext-ms-win-ntuser-window-l1.dll; \
ext-ms-win-rtcore-gdi-object-l1.dll; \
ext-ms-win-rtcore-gdi-rgn-l1.dll; \
ext-ms-win-rtcore-ntuser-cursor-l1.dll; \
ext-ms-win-rtcore-ntuser-dc-access-l1.dll; \
ext-ms-win-rtcore-ntuser-rawinput-l1.dll; \
ext-ms-win-rtcore-ntuser-sysparams-l1.dll; \
ext-ms-win-rtcore-ntuser-window-ext-l1.dll; \
ext-ms-win-rtcore-ntuser-winstamin-l1.dll; \
ext-ms-win-shell-shell32-l1.dll; \
ext-ms-win-uiacore-l1.dll; \
ext-ms-win-usp10-l1.dll; \
ext-ms-win-uxtheme-themes-l1.dll; \
DLOAD_ERROR_HANDLER = kernelbase DLOAD_ERROR_HANDLER = kernelbase

View File

@ -12,7 +12,7 @@
# Preprocessor Settings # Preprocessor Settings
# ------------------------------------- # -------------------------------------
C_DEFINES = $(C_DEFINES) -DBUILD_ONECORE_INTERACTIVITY C_DEFINES = $(C_DEFINES)
# ------------------------------------- # -------------------------------------
# Build System Settings # Build System Settings