mirror of
https://github.com/microsoft/terminal.git
synced 2026-05-21 06:18:34 +00:00
Compare commits
1 Commits
dev/duhowe
...
user/lheck
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa81e700ff |
364
OpenConsole.sln
364
OpenConsole.sln
File diff suppressed because it is too large
Load Diff
@@ -78,9 +78,6 @@ extends:
|
||||
cloudvault: # https://aka.ms/obpipelines/cloudvault
|
||||
enabled: false
|
||||
globalSdl: # https://aka.ms/obpipelines/sdl
|
||||
asyncSdl:
|
||||
enabled: true
|
||||
tsaOptionsFile: 'build/config/tsa.json'
|
||||
tsa:
|
||||
enabled: true
|
||||
configFile: '$(Build.SourcesDirectory)\build\config\tsa.json'
|
||||
|
||||
@@ -1,275 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "precomp.h"
|
||||
#include "LogIO.h"
|
||||
|
||||
using namespace Microsoft::Console::Host::BinaryLogging;
|
||||
|
||||
LoggingDeviceComm::LoggingDeviceComm(IDeviceComm* loggee, const std::wstring_view file) :
|
||||
_loggee(loggee),
|
||||
_lastEvent(std::chrono::high_resolution_clock::now())
|
||||
{
|
||||
_dataArena.resize(1024);
|
||||
_file.reset(CreateFileW(file.data(), GENERIC_WRITE | DELETE, FILE_SHARE_READ, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr));
|
||||
|
||||
USHORT processMachine{};
|
||||
USHORT nativeMachine{};
|
||||
THROW_IF_WIN32_BOOL_FALSE(IsWow64Process2(GetCurrentProcess(), &processMachine, &nativeMachine));
|
||||
|
||||
LogHeader header{};
|
||||
header.Version = 1;
|
||||
header.HostArchitecture = nativeMachine;
|
||||
_writeInFull(&header, sizeof(LogHeader));
|
||||
|
||||
//_startLogThread();
|
||||
}
|
||||
|
||||
[[nodiscard]] HRESULT LoggingDeviceComm::SetServerInformation(CD_IO_SERVER_INFORMATION* const pServerInfo) const
|
||||
{
|
||||
return _loggee->SetServerInformation(pServerInfo);
|
||||
}
|
||||
|
||||
[[nodiscard]] HRESULT LoggingDeviceComm::ReadIo(PCONSOLE_API_MSG const pReplyMsg, CONSOLE_API_MSG* const pMessage) const
|
||||
{
|
||||
RETURN_IF_FAILED(_loggee->ReadIo(pReplyMsg, pMessage));
|
||||
static constexpr uint32_t apiMsgLen{ sizeof(CONSOLE_API_MSG) - offsetof(CONSOLE_API_MSG, Descriptor) };
|
||||
_writeDataWithHeader(LogPacketType::Read, _timeDelta(), apiMsgLen, &pMessage->Descriptor);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
[[nodiscard]] HRESULT LoggingDeviceComm::CompleteIo(CD_IO_COMPLETE* const pCompletion) const
|
||||
{
|
||||
return _loggee->CompleteIo(pCompletion);
|
||||
}
|
||||
|
||||
[[nodiscard]] HRESULT LoggingDeviceComm::ReadInput(CD_IO_OPERATION* const pIoOperation) const
|
||||
{
|
||||
RETURN_IF_FAILED(_loggee->ReadInput(pIoOperation));
|
||||
_writeDataWithHeader(LogPacketType::InputBuffer, _timeDelta(), pIoOperation->Buffer.Size, pIoOperation->Buffer.Data);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
[[nodiscard]] HRESULT LoggingDeviceComm::WriteOutput(CD_IO_OPERATION* const pIoOperation) const
|
||||
{
|
||||
return _loggee->WriteOutput(pIoOperation);
|
||||
}
|
||||
|
||||
[[nodiscard]] HRESULT LoggingDeviceComm::AllowUIAccess() const
|
||||
{
|
||||
return _loggee->AllowUIAccess();
|
||||
}
|
||||
|
||||
[[nodiscard]] ULONG_PTR LoggingDeviceComm::PutHandle(const void* handle)
|
||||
{
|
||||
auto upstreamMapping{ _loggee->PutHandle(handle) };
|
||||
auto found{ std::find(_handleTable.begin(), _handleTable.end(), upstreamMapping) };
|
||||
if (found == _handleTable.end())
|
||||
{
|
||||
// append, get pos
|
||||
found = _handleTable.emplace(found, upstreamMapping);
|
||||
}
|
||||
return found - _handleTable.begin();
|
||||
}
|
||||
|
||||
[[nodiscard]] void* LoggingDeviceComm::GetHandle(ULONG_PTR handleId) const
|
||||
{
|
||||
return _loggee->GetHandle(_handleTable.at(handleId));
|
||||
}
|
||||
|
||||
void LoggingDeviceComm::DestroyHandle(ULONG_PTR handleId)
|
||||
{
|
||||
auto& pos{ _handleTable.at(handleId) };
|
||||
_loggee->DestroyHandle(pos);
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
uint64_t LoggingDeviceComm::_timeDelta() const
|
||||
{
|
||||
auto thisEventTime{ std::chrono::high_resolution_clock::now() };
|
||||
int64_t delta{ (thisEventTime - _lastEvent).count() };
|
||||
_lastEvent = thisEventTime;
|
||||
return delta;
|
||||
}
|
||||
|
||||
void LoggingDeviceComm::_writeInFull(void* buffer, const size_t length) const
|
||||
{
|
||||
auto remaining{ length };
|
||||
DWORD written{};
|
||||
while (WriteFile(_file.get(), reinterpret_cast<std::byte*>(buffer) + (length - remaining), gsl::narrow_cast<DWORD>(remaining), &written, nullptr) != 0)
|
||||
{
|
||||
if ((remaining -= written) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (remaining)
|
||||
{
|
||||
THROW_HR(E_BOUNDS);
|
||||
}
|
||||
}
|
||||
|
||||
void LoggingDeviceComm::_writeDataWithHeader(LogPacketType packetType, uint64_t timeDelta, size_t length, const void* buffer) const
|
||||
{
|
||||
auto fullPacketLen{ length + offsetof(LogPacketDescriptor, _PositionInFile) };
|
||||
if (_dataArena.size() < fullPacketLen)
|
||||
{
|
||||
_dataArena.resize(fullPacketLen);
|
||||
}
|
||||
*(reinterpret_cast<LogPacketDescriptor*>(_dataArena.data())) = LogPacketDescriptor{ packetType, timeDelta, gsl::narrow_cast<uint32_t>(length) };
|
||||
const auto bufferAsByte{ reinterpret_cast<const std::byte*>(buffer) };
|
||||
std::copy(bufferAsByte, bufferAsByte + length, _dataArena.data() + (offsetof(LogPacketDescriptor, _PositionInFile)));
|
||||
|
||||
_writeInFull(_dataArena.data(), fullPacketLen);
|
||||
}
|
||||
|
||||
void LoggingDeviceComm::_logThreadBody()
|
||||
{
|
||||
}
|
||||
|
||||
void LoggingDeviceComm::_startLogThread()
|
||||
{
|
||||
_logThread = std::thread{
|
||||
[this]() {
|
||||
_logThreadBody();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/******************************************************REPLAY********************************/
|
||||
|
||||
void LogReplayDeviceComm::_readInFull(void* buffer, const size_t length) const
|
||||
{
|
||||
/*
|
||||
auto remaining{ length };
|
||||
DWORD read{};
|
||||
while (!!ReadFile(_file.get(), reinterpret_cast<std::byte*>(buffer) + (length - remaining), gsl::narrow_cast<DWORD>(remaining), &read, nullptr))
|
||||
{
|
||||
if ((remaining -= read) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (remaining)
|
||||
{
|
||||
THROW_HR(E_BOUNDS);
|
||||
}
|
||||
*/
|
||||
if (length > _max - _off)
|
||||
{
|
||||
THROW_HR(E_BOUNDS);
|
||||
}
|
||||
memcpy(buffer, _fileMapView.get() + _off, length);
|
||||
_off += length;
|
||||
}
|
||||
|
||||
const LogPacketDescriptor& LogReplayDeviceComm::_readDescriptor() const
|
||||
{
|
||||
//LogPacketDescriptor descriptor{};
|
||||
//auto filepos{ SetFilePointer(_file.get(), 0, nullptr, FILE_CURRENT) };
|
||||
//_readInFull(&descriptor, offsetof(LogPacketDescriptor, _PositionInFile));
|
||||
//descriptor._PositionInFile = filepos;
|
||||
auto oldOff{ _off };
|
||||
_off += offsetof(LogPacketDescriptor, _PositionInFile);
|
||||
return *reinterpret_cast<LogPacketDescriptor*>(_fileMapView.get() + oldOff);
|
||||
//return descriptor;
|
||||
}
|
||||
|
||||
LogReplayDeviceComm::LogReplayDeviceComm(const std::wstring_view file, double timeDilation) :
|
||||
_timeDilation(timeDilation)
|
||||
{
|
||||
_file.reset(CreateFileW(file.data(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr));
|
||||
_fileMapping.reset(CreateFileMappingW(_file.get(), nullptr, PAGE_READONLY, 0, 0, nullptr));
|
||||
THROW_HR_IF_NULL(E_FAIL, _fileMapping);
|
||||
_fileMapView.reset(static_cast<std::byte*>(MapViewOfFile(_fileMapping.get(), FILE_MAP_READ, 0, 0, 0)));
|
||||
THROW_HR_IF_NULL(E_FAIL, _fileMapView);
|
||||
|
||||
MEMORY_BASIC_INFORMATION mbi{};
|
||||
VirtualQuery(_fileMapView.get(), &mbi, sizeof(mbi));
|
||||
_max = mbi.RegionSize;
|
||||
|
||||
USHORT processMachine{};
|
||||
USHORT nativeMachine{};
|
||||
THROW_IF_WIN32_BOOL_FALSE(IsWow64Process2(GetCurrentProcess(), &processMachine, &nativeMachine));
|
||||
|
||||
LogHeader header{};
|
||||
_readInFull(&header, sizeof(header));
|
||||
if (nativeMachine != header.HostArchitecture)
|
||||
{
|
||||
MessageBoxW(nullptr, wil::str_printf<std::wstring>(L"This dump was created on a conhost of a different architecture (expected %2.02x, got %2.02x).", header.HostArchitecture, nativeMachine).c_str(), L"Error", MB_OK | MB_ICONERROR);
|
||||
ExitProcess(1);
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] HRESULT LogReplayDeviceComm::SetServerInformation(CD_IO_SERVER_INFORMATION* const) const
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
[[nodiscard]] HRESULT LogReplayDeviceComm::ReadIo(PCONSOLE_API_MSG const, CONSOLE_API_MSG* const pMessage) const
|
||||
{
|
||||
auto requestStartTime{ std::chrono::high_resolution_clock::now() };
|
||||
|
||||
static constexpr uint32_t maxLen{ sizeof(CONSOLE_API_MSG) - offsetof(CONSOLE_API_MSG, Descriptor) };
|
||||
auto& descriptor{ _readDescriptor() };
|
||||
THROW_HR_IF(E_UNEXPECTED, descriptor.PacketType != LogPacketType::Read || descriptor.Length < maxLen);
|
||||
|
||||
_readInFull(&pMessage->Descriptor, descriptor.Length);
|
||||
|
||||
auto finishTime{ requestStartTime + std::chrono::nanoseconds(static_cast<long long>(descriptor.TimeDeltaInNs * _timeDilation)) };
|
||||
if (finishTime > std::chrono::high_resolution_clock::now())
|
||||
std::this_thread::sleep_until(finishTime);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
[[nodiscard]] HRESULT LogReplayDeviceComm::CompleteIo(CD_IO_COMPLETE* const) const
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
[[nodiscard]] HRESULT LogReplayDeviceComm::ReadInput(CD_IO_OPERATION* const pIoOperation) const
|
||||
{
|
||||
auto requestStartTime{ std::chrono::high_resolution_clock::now() };
|
||||
auto& descriptor{ _readDescriptor() };
|
||||
THROW_HR_IF(E_UNEXPECTED, descriptor.PacketType != LogPacketType::InputBuffer);
|
||||
|
||||
_readInFull(static_cast<uint8_t*>(pIoOperation->Buffer.Data), descriptor.Length);
|
||||
auto finishTime{ requestStartTime + std::chrono::nanoseconds(static_cast<long long>(descriptor.TimeDeltaInNs * _timeDilation)) };
|
||||
if (finishTime > std::chrono::high_resolution_clock::now())
|
||||
std::this_thread::sleep_until(finishTime);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
[[nodiscard]] HRESULT LogReplayDeviceComm::WriteOutput(CD_IO_OPERATION* const) const
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
[[nodiscard]] HRESULT LogReplayDeviceComm::AllowUIAccess() const
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
[[nodiscard]] ULONG_PTR LogReplayDeviceComm::PutHandle(const void* handle)
|
||||
{
|
||||
auto found{ std::find(_handleTable.begin(), _handleTable.end(), handle) };
|
||||
if (found == _handleTable.end())
|
||||
{
|
||||
// append, get pos
|
||||
found = _handleTable.emplace(found, const_cast<void*>(handle));
|
||||
}
|
||||
return found - _handleTable.begin();
|
||||
}
|
||||
|
||||
[[nodiscard]] void* LogReplayDeviceComm::GetHandle(ULONG_PTR handleId) const
|
||||
{
|
||||
return _handleTable.at(handleId);
|
||||
}
|
||||
|
||||
void LogReplayDeviceComm::DestroyHandle(ULONG_PTR handleId)
|
||||
{
|
||||
auto& pos{ _handleTable.at(handleId) };
|
||||
pos = nullptr;
|
||||
}
|
||||
111
src/host/LogIO.h
111
src/host/LogIO.h
@@ -1,111 +0,0 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- LogIO.h
|
||||
|
||||
Abstract:
|
||||
- TODO DH: Explain logging
|
||||
|
||||
Author:
|
||||
- Dustin Howett (DuHowett) 2020-11-14
|
||||
|
||||
Revision History:
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Microsoft::Console::Host::BinaryLogging
|
||||
{
|
||||
enum class LogPacketType : uint16_t
|
||||
{
|
||||
Read = 1,
|
||||
InputBuffer = 2,
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct LogHeader
|
||||
{
|
||||
uint8_t Version;
|
||||
uint16_t HostArchitecture;
|
||||
};
|
||||
|
||||
struct LogPacketDescriptor
|
||||
{
|
||||
LogPacketType PacketType;
|
||||
uint64_t TimeDeltaInNs;
|
||||
uint32_t Length;
|
||||
uint32_t _PositionInFile;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
class LoggingDeviceComm : public IDeviceComm
|
||||
{
|
||||
public:
|
||||
LoggingDeviceComm(IDeviceComm* loggee, const std::wstring_view file);
|
||||
~LoggingDeviceComm() = default;
|
||||
|
||||
[[nodiscard]] HRESULT SetServerInformation(_In_ CD_IO_SERVER_INFORMATION* const pServerInfo) const override;
|
||||
[[nodiscard]] HRESULT ReadIo(_In_opt_ PCONSOLE_API_MSG const pReplyMsg,
|
||||
_Out_ CONSOLE_API_MSG* const pMessage) const override;
|
||||
[[nodiscard]] HRESULT CompleteIo(_In_ CD_IO_COMPLETE* const pCompletion) const override;
|
||||
[[nodiscard]] HRESULT ReadInput(_In_ CD_IO_OPERATION* const pIoOperation) const override;
|
||||
[[nodiscard]] HRESULT WriteOutput(_In_ CD_IO_OPERATION* const pIoOperation) const override;
|
||||
[[nodiscard]] HRESULT AllowUIAccess() const override;
|
||||
[[nodiscard]] ULONG_PTR PutHandle(const void* handle) override;
|
||||
[[nodiscard]] void* GetHandle(ULONG_PTR handleId) const override;
|
||||
void DestroyHandle(ULONG_PTR handleId) override;
|
||||
[[nodiscard]] virtual HRESULT GetServerHandle(_Out_ HANDLE* pHandle) const { *pHandle = nullptr; return E_FAIL; }
|
||||
|
||||
private:
|
||||
wil::unique_hfile _file;
|
||||
IDeviceComm* _loggee;
|
||||
|
||||
mutable std::chrono::high_resolution_clock::time_point _lastEvent;
|
||||
std::vector<ULONG_PTR> _handleTable;
|
||||
|
||||
uint64_t _timeDelta() const;
|
||||
|
||||
mutable std::vector<std::byte> _dataArena;
|
||||
void _writeInFull(void* buffer, const size_t length) const;
|
||||
void _writeDataWithHeader(LogPacketType packetType, uint64_t timeDelta, size_t length, const void* buffer) const;
|
||||
|
||||
std::thread _logThread;
|
||||
void _logThreadBody();
|
||||
void _startLogThread();
|
||||
};
|
||||
|
||||
class LogReplayDeviceComm : public IDeviceComm
|
||||
{
|
||||
public:
|
||||
LogReplayDeviceComm(const std::wstring_view file, double timeDilation = 1.0);
|
||||
~LogReplayDeviceComm() = default;
|
||||
|
||||
[[nodiscard]] HRESULT SetServerInformation(_In_ CD_IO_SERVER_INFORMATION* const /*pServerInfo*/) const override;
|
||||
[[nodiscard]] HRESULT ReadIo(_In_opt_ PCONSOLE_API_MSG const /*pReplyMsg*/,
|
||||
_Out_ CONSOLE_API_MSG* const pMessage) const override;
|
||||
[[nodiscard]] HRESULT CompleteIo(_In_ CD_IO_COMPLETE* const /*pCompletion*/) const override;
|
||||
[[nodiscard]] HRESULT ReadInput(_In_ CD_IO_OPERATION* const pIoOperation) const override;
|
||||
[[nodiscard]] HRESULT WriteOutput(_In_ CD_IO_OPERATION* const /*pIoOperation*/) const override;
|
||||
[[nodiscard]] HRESULT AllowUIAccess() const override;
|
||||
[[nodiscard]] ULONG_PTR PutHandle(const void* handle) override;
|
||||
[[nodiscard]] void* GetHandle(ULONG_PTR handleId) const override;
|
||||
void DestroyHandle(ULONG_PTR handleId) override;
|
||||
[[nodiscard]] virtual HRESULT GetServerHandle(_Out_ HANDLE* pHandle) const { *pHandle = nullptr; return E_FAIL; }
|
||||
|
||||
private:
|
||||
wil::unique_hfile _file;
|
||||
double _timeDilation;
|
||||
std::vector<void*> _handleTable;
|
||||
|
||||
wil::unique_handle _fileMapping;
|
||||
wil::unique_mapview_ptr<std::byte> _fileMapView;
|
||||
mutable ptrdiff_t _off{ 0 };
|
||||
size_t _max{};
|
||||
|
||||
void _readInFull(void* buffer, const size_t length) const;
|
||||
|
||||
const LogPacketDescriptor& _readDescriptor() const;
|
||||
};
|
||||
}
|
||||
@@ -328,12 +328,7 @@ int CALLBACK wWinMain(
|
||||
if (useV2)
|
||||
#endif // TIL_FEATURE_LEGACYCONHOST_ENABLED
|
||||
{
|
||||
auto clientCommandLine{ args.GetClientCommandline() };
|
||||
if (clientCommandLine.rfind(L".bin") != std::wstring::npos)
|
||||
{
|
||||
hr = Entrypoints::StartConsoleForAPIDump(&args);
|
||||
}
|
||||
else if (args.ShouldCreateServerHandle())
|
||||
if (args.ShouldCreateServerHandle())
|
||||
{
|
||||
hr = Entrypoints::StartConsoleForCmdLine(args.GetClientCommandline().c_str(), &args);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
<ClCompile Include="..\VtApiRoutines.cpp" />
|
||||
<ClCompile Include="..\VtInputThread.cpp" />
|
||||
<ClCompile Include="..\VtIo.cpp" />
|
||||
<ClCompile Include="..\LogIO.cpp" />
|
||||
<ClCompile Include="..\writeData.cpp" />
|
||||
<ClCompile Include="..\_output.cpp" />
|
||||
<ClCompile Include="..\_stream.cpp" />
|
||||
@@ -101,7 +100,6 @@
|
||||
<ClInclude Include="..\VtApiRoutines.h" />
|
||||
<ClInclude Include="..\VtInputThread.hpp" />
|
||||
<ClInclude Include="..\VtIo.hpp" />
|
||||
<ClInclude Include="..\LogIO.hpp" />
|
||||
<ClInclude Include="..\writeData.hpp" />
|
||||
<ClInclude Include="..\_output.h" />
|
||||
<ClInclude Include="..\_stream.h" />
|
||||
|
||||
@@ -442,17 +442,10 @@ void COOKED_READ_DATA::_handleChar(wchar_t wch, const DWORD modifiers)
|
||||
// It's unclear whether the original intention was to write at the end of the buffer at all times or to implement an insert mode.
|
||||
// I went with insert mode.
|
||||
//
|
||||
// The old implementation also failed to clear the end of the prompt if you pressed tab in the middle of it.
|
||||
// You can reproduce this issue by launching cmd in an old conhost build and writing "<command that doesn't exist> foo",
|
||||
// moving your cursor to the space past the <command> and pressing tab. Nothing will happen but the "foo" will be inaccessible.
|
||||
// I've now fixed this behavior by adding an additional Replace() before the _flushBuffer() call that removes the tail end.
|
||||
//
|
||||
// It is important that we don't actually print that character out though, as it's only for the calling application to see.
|
||||
// That's why we flush the contents before the insertion and then ensure that the _flushBuffer() call in Read() exits early.
|
||||
const auto cursor = _buffer.GetCursorPosition();
|
||||
_buffer.Replace(cursor, npos, nullptr, 0);
|
||||
_flushBuffer();
|
||||
_buffer.Replace(cursor, 0, &wch, 1);
|
||||
_buffer.Replace(_buffer.GetCursorPosition(), 0, &wch, 1);
|
||||
_buffer.MarkAsClean();
|
||||
|
||||
_controlKeyState = modifiers;
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "renderData.hpp"
|
||||
#include "../renderer/base/renderer.hpp"
|
||||
|
||||
#include "LogIO.h"
|
||||
#include "../inc/conint.h"
|
||||
|
||||
#include "tracing.hpp"
|
||||
@@ -39,7 +38,6 @@
|
||||
|
||||
using namespace Microsoft::Console::Interactivity;
|
||||
using namespace Microsoft::Console::Render;
|
||||
using namespace Microsoft::Console::Host::BinaryLogging;
|
||||
|
||||
const UINT CONSOLE_EVENT_FAILURE_ID = 21790;
|
||||
const UINT CONSOLE_LPC_PORT_FAILURE_ID = 21791;
|
||||
@@ -52,20 +50,11 @@ try
|
||||
if (!Globals.pDeviceComm)
|
||||
{
|
||||
// in rare circumstances (such as in the fuzzing harness), there will already be a device comm
|
||||
if (!Server)
|
||||
{
|
||||
Globals.pDeviceComm = new LogReplayDeviceComm(args->GetClientCommandline(), 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto underlyingComm{ new ConDrvDeviceComm(Server) };
|
||||
Globals.pDeviceComm = new LoggingDeviceComm(underlyingComm, L"conhost_log.bin");
|
||||
}
|
||||
Globals.pDeviceComm = new ConDrvDeviceComm(Server);
|
||||
}
|
||||
|
||||
Globals.launchArgs = *args;
|
||||
|
||||
// TODO(DH) These should be part of the dump/trace
|
||||
Globals.uiOEMCP = GetOEMCP();
|
||||
Globals.uiWindowsCP = GetACP();
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
using pointer = const til::rect*;
|
||||
using reference = const til::rect&;
|
||||
|
||||
_bitmap_const_iterator(const dynamic_bitset<size_t, Allocator>& values, til::rect rc, ptrdiff_t pos) :
|
||||
_bitmap_const_iterator(const dynamic_bitset<unsigned long long, Allocator>& values, til::rect rc, ptrdiff_t pos) :
|
||||
_values(values),
|
||||
_rc(rc),
|
||||
_pos(pos),
|
||||
@@ -77,7 +77,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
}
|
||||
|
||||
private:
|
||||
const dynamic_bitset<size_t, Allocator>& _values;
|
||||
const dynamic_bitset<unsigned long long, Allocator>& _values;
|
||||
const til::rect _rc;
|
||||
size_t _pos;
|
||||
size_t _nextPos;
|
||||
@@ -133,7 +133,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Allocator = std::allocator<size_t>>
|
||||
template<typename Allocator = std::allocator<unsigned long long>>
|
||||
class bitmap
|
||||
{
|
||||
public:
|
||||
@@ -538,7 +538,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
allocator_type _alloc;
|
||||
til::size _sz;
|
||||
til::rect _rc;
|
||||
dynamic_bitset<size_t, allocator_type> _bits;
|
||||
dynamic_bitset<unsigned long long, allocator_type> _bits;
|
||||
|
||||
mutable std::optional<std::vector<til::rect, run_allocator_type>> _runs;
|
||||
|
||||
@@ -553,7 +553,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
|
||||
namespace pmr
|
||||
{
|
||||
using bitmap = ::til::details::bitmap<std::pmr::polymorphic_allocator<size_t>>;
|
||||
using bitmap = ::til::details::bitmap<std::pmr::polymorphic_allocator<unsigned long long>>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -265,7 +265,12 @@ void BackendD3D::_handleSettingsUpdate(const RenderingPayload& p)
|
||||
{
|
||||
wil::com_ptr<ID3D11Texture2D> buffer;
|
||||
THROW_IF_FAILED(p.swapChain.swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(buffer.addressof())));
|
||||
THROW_IF_FAILED(p.device->CreateRenderTargetView(buffer.get(), nullptr, _renderTargetView.put()));
|
||||
|
||||
static constexpr D3D11_RENDER_TARGET_VIEW_DESC desc{
|
||||
.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
|
||||
.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D,
|
||||
};
|
||||
THROW_IF_FAILED(p.device->CreateRenderTargetView(buffer.get(), &desc, _renderTargetView.put()));
|
||||
}
|
||||
|
||||
const auto fontChanged = _fontGeneration != p.s->font.generation();
|
||||
@@ -547,7 +552,7 @@ void BackendD3D::_recreateBackgroundColorBitmap(const RenderingPayload& p)
|
||||
.Height = p.s->viewportCellCount.y,
|
||||
.MipLevels = 1,
|
||||
.ArraySize = 1,
|
||||
.Format = DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||
.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
|
||||
.SampleDesc = { 1, 0 },
|
||||
.Usage = D3D11_USAGE_DYNAMIC,
|
||||
.BindFlags = D3D11_BIND_SHADER_RESOURCE,
|
||||
|
||||
@@ -35,6 +35,7 @@ float3 DWrite_EnhanceContrast3(float3 alpha, float k)
|
||||
return alpha * (k + 1.0f) / (alpha * k + 1.0f);
|
||||
}
|
||||
|
||||
// dwrite vs. gamma 1.8: https://www.desmos.com/calculator/6wocsr6vcq
|
||||
float DWrite_ApplyAlphaCorrection(float a, float f, float4 g)
|
||||
{
|
||||
return a + a * (1 - a) * ((g.x * f + g.y) * a + (g.z * f + g.w));
|
||||
|
||||
@@ -27,7 +27,7 @@ struct PSData
|
||||
float4 position : SV_Position;
|
||||
float2 texcoord : texcoord;
|
||||
nointerpolation uint shadingType : shadingType;
|
||||
nointerpolation uint2 renditionScale : renditionScale;
|
||||
nointerpolation float2 renditionScale : renditionScale;
|
||||
nointerpolation float4 color : color;
|
||||
};
|
||||
|
||||
|
||||
@@ -44,27 +44,13 @@ Output main(PSData data) : SV_Target
|
||||
}
|
||||
case SHADING_TYPE_TEXT_GRAYSCALE:
|
||||
{
|
||||
// These are independent of the glyph texture and could be moved to the vertex shader or CPU side of things.
|
||||
const float4 foreground = premultiplyColor(data.color);
|
||||
const float blendEnhancedContrast = DWrite_ApplyLightOnDarkContrastAdjustment(enhancedContrast, data.color.rgb);
|
||||
const float intensity = DWrite_CalcColorIntensity(data.color.rgb);
|
||||
// These aren't.
|
||||
const float4 glyph = glyphAtlas[data.texcoord];
|
||||
const float contrasted = DWrite_EnhanceContrast(glyph.a, blendEnhancedContrast);
|
||||
const float alphaCorrected = DWrite_ApplyAlphaCorrection(contrasted, intensity, gammaRatios);
|
||||
color = alphaCorrected * foreground;
|
||||
color = glyphAtlas[data.texcoord].a * data.color;
|
||||
weights = color.aaaa;
|
||||
break;
|
||||
}
|
||||
case SHADING_TYPE_TEXT_CLEARTYPE:
|
||||
{
|
||||
// These are independent of the glyph texture and could be moved to the vertex shader or CPU side of things.
|
||||
const float blendEnhancedContrast = DWrite_ApplyLightOnDarkContrastAdjustment(enhancedContrast, data.color.rgb);
|
||||
// These aren't.
|
||||
const float4 glyph = glyphAtlas[data.texcoord];
|
||||
const float3 contrasted = DWrite_EnhanceContrast3(glyph.rgb, blendEnhancedContrast);
|
||||
const float3 alphaCorrected = DWrite_ApplyAlphaCorrection3(contrasted, data.color.rgb, gammaRatios);
|
||||
weights = float4(alphaCorrected * data.color.a, 1);
|
||||
weights = float4(glyphAtlas[data.texcoord].rgb * data.color.a, 1);
|
||||
color = weights * data.color;
|
||||
break;
|
||||
}
|
||||
@@ -77,14 +63,14 @@ Output main(PSData data) : SV_Target
|
||||
case SHADING_TYPE_DOTTED_LINE:
|
||||
{
|
||||
const bool on = frac(data.position.x / (2.0f * underlineWidth * data.renditionScale.x)) < 0.5f;
|
||||
color = on * premultiplyColor(data.color);
|
||||
color = on * data.color;
|
||||
weights = color.aaaa;
|
||||
break;
|
||||
}
|
||||
case SHADING_TYPE_DASHED_LINE:
|
||||
{
|
||||
const bool on = frac(data.position.x / (backgroundCellSize.x * data.renditionScale.x)) < 0.5f;
|
||||
color = on * premultiplyColor(data.color);
|
||||
color = on * data.color;
|
||||
weights = color.aaaa;
|
||||
break;
|
||||
}
|
||||
@@ -102,13 +88,13 @@ Output main(PSData data) : SV_Target
|
||||
const float s = sin(data.position.x * freq);
|
||||
const float d = abs(centerY - (s * amp) - data.position.y);
|
||||
const float a = 1 - saturate(d - strokeWidthHalf);
|
||||
color = a * premultiplyColor(data.color);
|
||||
color = a * data.color;
|
||||
weights = color.aaaa;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
color = premultiplyColor(data.color);
|
||||
color = data.color;
|
||||
weights = color.aaaa;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include "shader_common.hlsl"
|
||||
|
||||
#pragma warning(disable: 3571) // pow(f, e) will not work for negative f, use abs(f) or conditionally handle negative values if you expect them
|
||||
|
||||
cbuffer ConstBuffer : register(b0)
|
||||
{
|
||||
float2 positionScale;
|
||||
@@ -13,7 +15,7 @@ PSData main(VSData data)
|
||||
// clang-format on
|
||||
{
|
||||
PSData output;
|
||||
output.color = data.color;
|
||||
output.color = float4(pow(data.color.rgb * data.color.a, 2.2), data.color.a);
|
||||
output.shadingType = data.shadingType;
|
||||
output.renditionScale = data.renditionScale;
|
||||
// positionScale is expected to be float2(2.0f / sizeInPixel.x, -2.0f / sizeInPixel.y). Together with the
|
||||
|
||||
@@ -172,11 +172,6 @@ ConDrvDeviceComm::~ConDrvDeviceComm() = default;
|
||||
return reinterpret_cast<void*>(handleId);
|
||||
}
|
||||
|
||||
void ConDrvDeviceComm::DestroyHandle(ULONG_PTR /*handleId*/)
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
|
||||
// Routine Description:
|
||||
// - Provides access to the raw server handle so it can be used to hand off
|
||||
// the session to another console host server.
|
||||
|
||||
@@ -39,7 +39,6 @@ public:
|
||||
|
||||
[[nodiscard]] ULONG_PTR PutHandle(const void*) override;
|
||||
[[nodiscard]] void* GetHandle(ULONG_PTR) const override;
|
||||
void DestroyHandle(ULONG_PTR) override;
|
||||
|
||||
[[nodiscard]] HRESULT GetServerHandle(_Out_ HANDLE* pHandle) const override;
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ public:
|
||||
|
||||
[[nodiscard]] virtual ULONG_PTR PutHandle(const void*) = 0;
|
||||
[[nodiscard]] virtual void* GetHandle(ULONG_PTR) const = 0;
|
||||
virtual void DestroyHandle(ULONG_PTR) = 0;
|
||||
|
||||
[[nodiscard]] virtual HRESULT GetServerHandle(_Out_ HANDLE* pHandle) const = 0;
|
||||
};
|
||||
|
||||
@@ -176,16 +176,4 @@
|
||||
FAIL_FAST_HR(E_UNEXPECTED);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
[[nodiscard]] HRESULT Entrypoints::StartConsoleForAPIDump(const ConsoleArguments* const args)
|
||||
{
|
||||
// Create a scope because we're going to exit thread if everything goes well.
|
||||
// This scope will ensure all C++ objects and smart pointers get a chance to destruct before ExitThread is called.
|
||||
RETURN_IF_FAILED(ConsoleCreateIoThreadLegacy(nullptr, args));
|
||||
ExitThread(S_OK);
|
||||
|
||||
// We won't hit this. The ExitThread above will kill the caller at this point.
|
||||
FAIL_FAST_HR(E_UNEXPECTED);
|
||||
return S_OK;
|
||||
}
|
||||
#pragma warning(pop)
|
||||
|
||||
@@ -22,5 +22,4 @@ namespace Entrypoints
|
||||
{
|
||||
[[nodiscard]] HRESULT StartConsoleForServerHandle(const HANDLE ServerHandle, const ConsoleArguments* const args);
|
||||
[[nodiscard]] HRESULT StartConsoleForCmdLine(_In_ PCWSTR pwszCmdLine, const ConsoleArguments* const args);
|
||||
[[nodiscard]] HRESULT StartConsoleForAPIDump(const ConsoleArguments* const args);
|
||||
};
|
||||
|
||||
@@ -147,4 +147,4 @@
|
||||
<ItemGroup>
|
||||
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net461</TargetFramework>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -20,6 +20,14 @@
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
|
||||
Reference in New Issue
Block a user