Obstruct the user when they try to run WT under WOW (#1648)

* Obstruct the user when they try to run under WOW

* Move strings to resource file, add comments to methods, remove extraneous wil include.

* remove excess newline

* output of formatter.
This commit is contained in:
Dustin L. Howett (MSFT) 2019-07-11 10:23:23 -07:00 committed by msftbot[bot]
parent 594a7e4501
commit 60a444c630
4 changed files with 128 additions and 8 deletions

View file

@ -17,6 +17,7 @@
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
@ -24,18 +25,18 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// TEXTINCLUDE
//
1 TEXTINCLUDE
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
@ -44,11 +45,36 @@ END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_APPICON ICON "..\\..\\..\\res\\terminal.ico"
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_ERROR_DIALOG_TITLE "Error"
IDS_ERROR_ARCHITECTURE_FORMAT
"Windows Terminal is designed to run on your system's native architecture (%s).\nYou are currently using the %s version.\n\nPlease use the version of Windows Terminal that matches your system's native architecture."
IDS_X86_ARCHITECTURE "i386"
END
STRINGTABLE
BEGIN
IDS_AMD64_ARCHITECTURE "AMD64"
IDS_ARM64_ARCHITECTURE "ARM64"
IDS_ARM_ARCHITECTURE "ARM"
IDS_UNKNOWN_ARCHITECTURE "Unknown"
END
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
@ -65,4 +91,3 @@ END
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
IDI_APPICON ICON "..\\..\\..\\res\\terminal.ico"

View file

@ -3,6 +3,7 @@
#include "pch.h"
#include "AppHost.h"
#include "resource.h"
using namespace winrt;
using namespace Windows::UI;
@ -10,8 +11,94 @@ using namespace Windows::UI::Composition;
using namespace Windows::UI::Xaml::Hosting;
using namespace Windows::Foundation::Numerics;
// Routine Description:
// - Retrieves the string resource from the current module with the given ID
// from the resources files. See resource.h and the .rc definitions for valid IDs.
// Arguments:
// - id - Resource ID
// Return Value:
// - String resource retrieved from that ID.
static std::wstring GetStringResource(const UINT id)
{
// Calling LoadStringW with a pointer-sized storage and no length will return a read-only pointer
// directly to the resource data instead of copying it immediately into a buffer.
LPWSTR readOnlyResource = nullptr;
const auto length = LoadStringW(wil::GetModuleInstanceHandle(),
id,
reinterpret_cast<LPWSTR>(&readOnlyResource),
0);
// However, the pointer and length given are NOT guaranteed to be zero-terminated
// and most uses of this data will probably want a zero-terminated string.
// So we're going to construct and return a std::wstring copy from the pointer/length
// since those are certainly zero-terminated.
return { readOnlyResource, gsl::narrow<size_t>(length) };
}
// Routine Description:
// - Takes an image architecture and locates a string resource that maps to that architecture.
// Arguments:
// - imageArchitecture - An IMAGE_FILE_MACHINE architecture enum value
// - See https://docs.microsoft.com/en-us/windows/win32/sysinfo/image-file-machine-constants
// Return Value:
// - A string value representing the human-readable name of this architecture.
static std::wstring ImageArchitectureToString(USHORT imageArchitecture)
{
// clang-format off
const auto id = imageArchitecture == IMAGE_FILE_MACHINE_I386 ? IDS_X86_ARCHITECTURE :
imageArchitecture == IMAGE_FILE_MACHINE_AMD64 ? IDS_AMD64_ARCHITECTURE :
imageArchitecture == IMAGE_FILE_MACHINE_ARM64 ? IDS_ARM64_ARCHITECTURE :
imageArchitecture == IMAGE_FILE_MACHINE_ARM ? IDS_ARM_ARCHITECTURE :
IDS_UNKNOWN_ARCHITECTURE;
// clang-format on
return GetStringResource(id);
}
// Routine Description:
// - Blocks the user from launching the application with a message box dialog and early exit
// if the process architecture doesn't match the system platform native architecture.
// - This is because the conhost.exe must match the condrv.sys on the system and the PTY
// infrastructure that powers everything won't work if we have a mismatch.
// Arguments:
// - <none>
// Return Value:
// - <none>
static void EnsureNativeArchitecture()
{
USHORT processMachine{};
USHORT nativeMachine{};
THROW_IF_WIN32_BOOL_FALSE(IsWow64Process2(GetCurrentProcess(), &processMachine, &nativeMachine));
if (processMachine != IMAGE_FILE_MACHINE_UNKNOWN && processMachine != nativeMachine)
{
const auto formatPattern = GetStringResource(IDS_ERROR_ARCHITECTURE_FORMAT);
const auto nativeArchitecture = ImageArchitectureToString(nativeMachine);
const auto processArchitecture = ImageArchitectureToString(processMachine);
const auto lengthRequired = _scwprintf(formatPattern.data(), nativeArchitecture.data(), processArchitecture.data());
const auto bufferSize = lengthRequired + 1;
std::wstring buffer;
buffer.resize(bufferSize);
swprintf_s(buffer.data(), buffer.size(), formatPattern.data(), nativeArchitecture.data(), processArchitecture.data());
MessageBoxW(nullptr,
buffer.data(),
GetStringResource(IDS_ERROR_DIALOG_TITLE).data(),
MB_OK | MB_ICONERROR);
ExitProcess(0);
}
}
int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
{
// Block the user from starting if they launched the incorrect architecture version of the project.
// This should only be applicable to developer versions. The package installation process
// should choose and install the correct one from the bundle.
EnsureNativeArchitecture();
// Make sure to call this so we get WM_POINTER messages.
EnableMouseInPointer(true);

View file

@ -50,3 +50,4 @@ Abstract:
#include <winrt/Windows.ui.xaml.media.h>
#include <wil/resource.h>
#include <wil/win32_helpers.h>

View file

@ -1,16 +1,23 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Cascadia.EXE.rc
// Used by WindowsTerminal.rc
//
#define IDI_APPICON 101
#define IDS_ERROR_DIALOG_TITLE 105
#define IDS_ERROR_ARCHITECTURE_FORMAT 110
#define IDS_X86_ARCHITECTURE 111
#define IDS_AMD64_ARCHITECTURE 112
#define IDS_ARM64_ARCHITECTURE 113
#define IDS_ARM_ARCHITECTURE 114
#define IDS_UNKNOWN_ARCHITECTURE 115
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_RESOURCE_VALUE 104
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
#define IDI_APPICON 101