Merge remote-tracking branch 'origin/main' into dev/migrie/f/remoting.dll

This commit is contained in:
Mike Griese 2021-01-07 14:59:41 -06:00
commit 88ffc6fc0e
26 changed files with 246 additions and 151 deletions

View file

@ -59,6 +59,7 @@ OUTLINETEXTMETRICW
overridable
PAGESCROLL
REGCLS
pmr
RETURNCMD
rfind
roundf

View file

@ -0,0 +1,14 @@
checkboxes
CSIDL
csv
horiz
IDispatch
inlines
IWeb
Progman
reserialize
SHANDLE
SHGFP
udk
unfocus
WClass

View file

@ -168,7 +168,6 @@ BOLDFONT
BOOLIFY
bools
boostorg
Bopomofo
Borland
BOTTOMLEFT
BOTTOMRIGHT
@ -248,7 +247,6 @@ charset
CHARSETINFO
chcp
checkbox
Checkboxes
chh
Childitem
chk
@ -384,7 +382,6 @@ CORESYSTEM
cotaskmem
countof
cout
CParams
CPG
cpinfo
CPINFOEX
@ -413,7 +410,6 @@ csbi
csbiex
csharp
CSHORT
cso
csproj
Csr
csrmsg
@ -426,7 +422,6 @@ cstdlib
cstr
cstring
cstyle
CSV
CSwitch
CText
ctime
@ -628,7 +623,6 @@ doskey
dotnet
doubleclick
downlevel
DOWNSCALE
dpg
dpi
DPIAPI
@ -841,7 +835,6 @@ gcy
gdi
gdip
gdirenderer
GENERATEPROJECTPRIFILE
geopol
GETALIAS
GETALIASES
@ -957,7 +950,6 @@ hfont
hglobal
hh
hhh
hhhh
hhook
hhx
HIBYTE
@ -984,7 +976,6 @@ hmod
hmodule
hmon
HMONITOR
Horiz
HORZ
hostable
hostlib
@ -1097,10 +1088,8 @@ INITMENU
inkscape
inl
INLINEPREFIX
Inlines
INotify
inout
INPATHROOT
inproc
Inputkeyinfo
INPUTPROCESSORPROFILE
@ -1113,7 +1102,6 @@ INTERCEPTCOPYPASTE
INTERNALNAME
interop
interoperability
intersectors
inthread
intptr
intsafe
@ -1212,7 +1200,6 @@ KJ
KLF
KLMNOPQRST
KLMNOPQRSTQQQQQ
Kode
KU
KVM
KX
@ -1344,7 +1331,6 @@ mailto
majorly
makeappx
MAKEINTRESOURCE
MAKEINTRESOURCEA
MAKEINTRESOURCEW
MAKELANGID
MAKELONG
@ -1417,7 +1403,6 @@ monostate
MOUSEACTIVATE
MOUSEFIRST
MOUSEHWHEEL
mousemode
MOUSEMOVE
mousewheel
MOVESTART
@ -1439,7 +1424,6 @@ MSGSELECTMODE
msiexec
MSIL
msix
msixbundle
msrc
msvcrt
MSVS
@ -1842,7 +1826,6 @@ pshn
PSHNOTIFY
PSHORT
pshpack
psin
PSINGLE
psl
psldl
@ -1962,16 +1945,13 @@ Replymessage
repositorypath
rescap
Resequence
Reserialize
RESETCONTENT
resheader
resizable
resmimetype
reso
restrictedcapabilities
resw
resx
RETROII
retval
rfa
rfc
@ -1991,7 +1971,6 @@ rgpwsz
rgrc
rgs
rgui
rgus
rgw
rgwch
rhs
@ -2042,14 +2021,11 @@ SBCSDBCS
sbi
sbiex
sbold
sbri
scanbri
scancode
scanline
schemename
SCL
scm
scol
scprintf
SCRBUF
SCRBUFSIZE
@ -2128,7 +2104,6 @@ sfi
SFINAE
SFUI
sgr
SGRXY
SHCo
shcore
shellapi
@ -2183,9 +2158,6 @@ SOURCESDIRECTORY
SPACEBAR
spammy
spand
spe
sph
spherefunctions
splashscreen
sprintf
sqlproj
@ -2303,7 +2275,6 @@ TCI
tcome
tcommandline
tcommands
tcon
TDelegated
TDP
TEAMPROJECT
@ -2449,8 +2420,6 @@ ucdxml
uch
UCHAR
ucs
UDK
UDKs
UDM
uer
uget
@ -2473,7 +2442,6 @@ UNCPRIORITY
undef
Unescape
unexpand
Unfocus
unhighlighting
unhosted
unicode
@ -2564,7 +2532,6 @@ vga
vgaoem
viewkind
viewports
Viginetting
Virt
VIRTTERM
Virtualizing
@ -2781,7 +2748,6 @@ wwaproj
WWith
wx
wxh
wz
xa
xact
xamarin
@ -2800,14 +2766,12 @@ XColors
xcopy
XCount
xdy
xe
XEncoding
xes
Xes
XES
xff
XFile
xlang
XManifest
XMath
XMFLOAT
@ -2831,9 +2795,7 @@ xutr
xvalue
XVIRTUALSCREEN
XWalk
XWV
xy
xyw
Xzn
yact
YAML
@ -2850,7 +2812,6 @@ YVIRTUALSCREEN
Yw
YWalk
yx
yzx
Zc
ZCmd
ZCtrl
@ -2862,7 +2823,6 @@ zu
zxcvbnm
zy
AAAAABBBBBBCCC
AAAAA
BBBBBCCC
abcd
LPMINMAXINFO

View file

@ -184,15 +184,15 @@ size_t ATTR_ROW::FindAttrIndex(const size_t index, size_t* const pApplies) const
// Routine Description:
// - Finds the hyperlink IDs present in this row and returns them
// Return value:
// - An unordered set containing the hyperlink IDs present in this row
std::unordered_set<uint16_t> ATTR_ROW::GetHyperlinks()
// - The hyperlink IDs present in this row
std::vector<uint16_t> ATTR_ROW::GetHyperlinks()
{
std::unordered_set<uint16_t> ids;
std::vector<uint16_t> ids;
for (const auto& run : _list)
{
if (run.GetAttributes().IsHyperlink())
{
ids.emplace(run.GetAttributes().GetHyperlinkId());
ids.emplace_back(run.GetAttributes().GetHyperlinkId());
}
}
return ids;

View file

@ -20,7 +20,6 @@ Revision History:
#pragma once
#include "boost/container/small_vector.hpp"
#include "TextAttributeRun.hpp"
#include "AttrRowIterator.hpp"
@ -51,7 +50,7 @@ public:
size_t FindAttrIndex(const size_t index,
size_t* const pApplies) const;
std::unordered_set<uint16_t> GetHyperlinks();
std::vector<uint16_t> GetHyperlinks();
bool SetAttrToEnd(const UINT iStart, const TextAttribute attr);
void ReplaceAttrs(const TextAttribute& toBeReplacedAttr, const TextAttribute& replaceWith) noexcept;

View file

@ -15,7 +15,6 @@ Author(s):
#pragma once
#include "boost/container/small_vector.hpp"
#include "TextAttribute.hpp"
#include "TextAttributeRun.hpp"

View file

@ -24,7 +24,6 @@ Revision History:
#include "CharRowCellReference.hpp"
#include "CharRowCell.hpp"
#include "UnicodeStorage.hpp"
#include "boost/container/small_vector.hpp"
class ROW;

View file

@ -1230,9 +1230,15 @@ void TextBuffer::_PruneHyperlinks()
// If the buffer does not contain the same reference, we can remove that hyperlink from our map
// This way, obsolete hyperlink references are cleared from our hyperlink map instead of hanging around
// Get all the hyperlink references in the row we're erasing
auto firstRowRefs = _storage.at(_firstRow).GetAttrRow().GetHyperlinks();
if (!firstRowRefs.empty())
const auto hyperlinks = _storage.at(_firstRow).GetAttrRow().GetHyperlinks();
if (!hyperlinks.empty())
{
// Move to unordered set so we can use hashed lookup of IDs instead of linear search.
// Only make it an unordered set now because set always heap allocates but vector
// doesn't when the set is empty (saving an allocation in the common case of no links.)
std::unordered_set<uint16_t> firstRowRefs{ hyperlinks.cbegin(), hyperlinks.cend() };
const auto total = TotalRowCount();
// Loop through all the rows in the buffer except the first row -
// we have found all hyperlink references in the first row and put them in refs,
@ -1254,12 +1260,12 @@ void TextBuffer::_PruneHyperlinks()
break;
}
}
}
// Now delete obsolete references from our map
for (auto hyperlinkReference : firstRowRefs)
{
RemoveHyperlinkFromMap(hyperlinkReference);
// Now delete obsolete references from our map
for (auto hyperlinkReference : firstRowRefs)
{
RemoveHyperlinkFromMap(hyperlinkReference);
}
}
}

View file

@ -82,14 +82,9 @@
<desktop5:ItemType Type="Directory">
<desktop5:Verb Id="Command1" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
</desktop5:ItemType>
<!-- Due to a bug in the OS, this doesn't actually work right -
we'll get a nullptr in our implementation. So this is disabled
temporarily. See MSFT:24623699 for more details.
<desktop5:ItemType Type="Directory\Background">
<desktop5:Verb Id="Command2" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
</desktop5:ItemType>
-->
<desktop5:Verb Id="Command2" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
</desktop5:ItemType>
</desktop4:FileExplorerContextMenus>
</desktop4:Extension>

View file

@ -82,15 +82,9 @@
<desktop5:ItemType Type="Directory">
<desktop5:Verb Id="Command1" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
</desktop5:ItemType>
<!-- Due to a bug in the OS, this doesn't actually work right -
we'll get a nullptr in our implementation. So this is disabled
temporarily. See MSFT:24623699 for more details.
<desktop5:ItemType Type="Directory\Background">
<desktop5:Verb Id="Command2" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
<desktop5:Verb Id="Command2" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
</desktop5:ItemType>
-->
</desktop4:FileExplorerContextMenus>
</desktop4:Extension>

View file

@ -83,14 +83,9 @@
<desktop5:ItemType Type="Directory">
<desktop5:Verb Id="Command1" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
</desktop5:ItemType>
<!-- Due to a bug in the OS, this doesn't actually work right -
we'll get a nullptr in our implementation. So this is disabled
temporarily. See MSFT:24623699 for more details.
<desktop5:ItemType Type="Directory\Background">
<desktop5:Verb Id="Command2" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
<desktop5:Verb Id="Command2" Clsid="9f156763-7844-4dc4-b2b1-901f640f5155" />
</desktop5:ItemType>
-->
</desktop4:FileExplorerContextMenus>
</desktop4:Extension>

View file

@ -3,6 +3,7 @@
#include "pch.h"
#include "OpenTerminalHere.h"
#include <ShlObj.h>
// TODO GH#6112: Localize these strings
static constexpr std::wstring_view VerbDisplayName{ L"Open in Windows Terminal" };
@ -117,14 +118,29 @@ static std::wstring _getExePath()
HRESULT OpenTerminalHere::Invoke(IShellItemArray* psiItemArray,
IBindCtx* /*pBindContext*/)
{
DWORD count;
psiItemArray->GetCount(&count);
winrt::com_ptr<IShellItem> psi;
RETURN_IF_FAILED(psiItemArray->GetItemAt(0, psi.put()));
wil::unique_cotaskmem_string pszName;
RETURN_IF_FAILED(psi->GetDisplayName(SIGDN_FILESYSPATH, &pszName));
if (psiItemArray == nullptr)
{
// get the current path from explorer.exe
const auto path = this->_GetPathFromExplorer();
// no go, unable to get a reasonable path
if (path.empty())
{
return S_FALSE;
}
pszName = wil::make_cotaskmem_string(path.c_str(), path.length());
}
else
{
DWORD count;
psiItemArray->GetCount(&count);
winrt::com_ptr<IShellItem> psi;
RETURN_IF_FAILED(psiItemArray->GetItemAt(0, psi.put()));
RETURN_IF_FAILED(psi->GetDisplayName(SIGDN_FILESYSPATH, &pszName));
}
{
wil::unique_process_information _piClient;
@ -214,3 +230,90 @@ HRESULT OpenTerminalHere::EnumSubCommands(IEnumExplorerCommand** ppEnum)
*ppEnum = nullptr;
return E_NOTIMPL;
}
std::wstring OpenTerminalHere::_GetPathFromExplorer() const
{
using namespace std;
using namespace winrt;
wstring path;
HRESULT hr = NOERROR;
auto hwnd = ::GetForegroundWindow();
if (hwnd == nullptr)
{
return path;
}
TCHAR szName[MAX_PATH] = { 0 };
::GetClassName(hwnd, szName, MAX_PATH);
if (0 == StrCmp(szName, L"WorkerW") ||
0 == StrCmp(szName, L"Progman"))
{
//special folder: desktop
hr = ::SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, SHGFP_TYPE_CURRENT, szName);
if (FAILED(hr))
{
return path;
}
path = szName;
return path;
}
if (0 != StrCmp(szName, L"CabinetWClass"))
{
return path;
}
auto shell = create_instance<IShellWindows>(CLSID_ShellWindows);
if (shell == nullptr)
{
return path;
}
com_ptr<IDispatch> disp;
wil::unique_variant variant;
variant.vt = VT_I4;
com_ptr<IWebBrowserApp> browser;
// look for correct explorer window
for (variant.intVal = 0;
shell->Item(variant, disp.put()) == S_OK;
variant.intVal++)
{
com_ptr<IWebBrowserApp> tmp;
if (FAILED(disp->QueryInterface(tmp.put())))
{
continue;
}
HWND tmpHWND = NULL;
hr = tmp->get_HWND(reinterpret_cast<SHANDLE_PTR*>(&tmpHWND));
if (hwnd == tmpHWND)
{
browser = tmp;
break; //found
}
}
if (browser != nullptr)
{
wil::unique_bstr url;
hr = browser->get_LocationURL(&url);
if (FAILED(hr))
{
return path;
}
wstring sUrl(url.get(), SysStringLen(url.get()));
DWORD size = MAX_PATH;
hr = ::PathCreateFromUrl(sUrl.c_str(), szName, &size, NULL);
if (SUCCEEDED(hr))
{
path = szName;
}
}
return path;
}

View file

@ -46,6 +46,9 @@ struct __declspec(uuid("9f156763-7844-4dc4-b2b1-901f640f5155"))
STDMETHODIMP GetCanonicalName(GUID* pguidCommandName);
STDMETHODIMP EnumSubCommands(IEnumExplorerCommand** ppEnum);
#pragma endregion
private:
std::wstring _GetPathFromExplorer() const;
};
CoCreatableClass(OpenTerminalHere);

View file

@ -11,10 +11,13 @@
<!-- sets a bunch of Windows Universal properties -->
<OpenConsoleUniversalApp>true</OpenConsoleUniversalApp>
</PropertyGroup>
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
<ItemDefinitionGroup>
<Link>
<AdditionalDependencies>User32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="OpenTerminalHere.h" />
@ -40,7 +43,6 @@
<None Include="packages.config" />
<None Include="WindowsTerminalShellExt.def" />
</ItemGroup>
<!-- ========================= Project References ======================== -->
<ItemGroup>
<!--
@ -56,7 +58,5 @@
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
</Project>

View file

@ -81,6 +81,5 @@
<AdditionalDependencies>$(OpenConsoleCommonOutDir)\conptylib.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
</Project>

View file

@ -88,8 +88,6 @@ TRACELOGGING_DECLARE_PROVIDER(g_hConhostV2EventTraceProvider);
#include "../inc/operators.hpp"
#include "../inc/conattrs.hpp"
#include "boost/container/small_vector.hpp"
// TODO: MSFT 9355094 Find a better way of doing this. http://osgvsowi/9355094
[[nodiscard]] inline NTSTATUS NTSTATUS_FROM_HRESULT(HRESULT hr)
{

View file

@ -210,13 +210,13 @@ void Tracing::s_TraceApi(const CONSOLE_SCREENBUFFERINFO_MSG* const a)
static_assert(sizeof(UINT32) == sizeof(*a->ColorTable), "a->ColorTable");
}
void Tracing::s_TraceApi(const CONSOLE_MODE_MSG* const a, const std::wstring& handleType)
void Tracing::s_TraceApi(const CONSOLE_MODE_MSG* const a, const std::wstring_view handleType)
{
TraceLoggingWrite(
g_hConhostV2EventTraceProvider,
"API_GetConsoleMode",
TraceLoggingHexUInt32(a->Mode, "Mode"),
TraceLoggingWideString(handleType.c_str(), "Handle type"),
TraceLoggingCountedWideString(handleType.data(), gsl::narrow_cast<ULONG>(handleType.size()), "Handle type"),
TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE),
TraceLoggingKeyword(TraceKeywords::API));
}

View file

@ -50,7 +50,7 @@ public:
static void s_TraceApi(_In_ const void* const buffer, const CONSOLE_WRITECONSOLE_MSG* const a);
static void s_TraceApi(const CONSOLE_SCREENBUFFERINFO_MSG* const a);
static void s_TraceApi(const CONSOLE_MODE_MSG* const a, const std::wstring& handleType);
static void s_TraceApi(const CONSOLE_MODE_MSG* const a, const std::wstring_view handleType);
static void s_TraceApi(const CONSOLE_SETTEXTATTRIBUTE_MSG* const a);
static void s_TraceApi(const CONSOLE_WRITECONSOLEOUTPUTSTRING_MSG* const a);

View file

@ -23,6 +23,7 @@
#include <deque>
#include <list>
#include <memory>
#include <memory_resource>
#include <map>
#include <mutex>
#include <shared_mutex>
@ -74,6 +75,9 @@
#include <base/numerics/safe_math.h>
#pragma warning(pop)
// Boost
#include "boost/container/small_vector.hpp"
// IntSafe
#define ENABLE_INTSAFE_SIGNED_FUNCTIONS
#include <intsafe.h>

View file

@ -86,13 +86,12 @@ void SystemConfigurationProvider::GetSettingsFromLink(
CONSOLE_STATE_INFO csi = pLinkSettings->CreateConsoleStateInfo();
csi.LinkTitle = linkNameForCsi;
WCHAR wszShortcutTitle[MAX_PATH];
BOOL fReadConsoleProperties;
WCHAR wszShortcutTitle[MAX_PATH] = L"\0";
BOOL fReadConsoleProperties = FALSE;
WORD wShowWindow = pLinkSettings->GetShowWindow();
DWORD dwHotKey = pLinkSettings->GetHotKey();
int iShowWindow;
WORD wHotKey;
int iShowWindow = 0;
WORD wHotKey = 0;
NTSTATUS Status = ShortcutSerialization::s_GetLinkValues(&csi,
&fReadConsoleProperties,
wszShortcutTitle,
@ -105,19 +104,22 @@ void SystemConfigurationProvider::GetSettingsFromLink(
&iShowWindow,
&wHotKey);
// Convert results back to appropriate types and set.
if (SUCCEEDED(IntToWord(iShowWindow, &wShowWindow)))
if (NT_SUCCESS(Status))
{
pLinkSettings->SetShowWindow(wShowWindow);
}
// Convert results back to appropriate types and set.
if (SUCCEEDED(IntToWord(iShowWindow, &wShowWindow)))
{
pLinkSettings->SetShowWindow(wShowWindow);
}
dwHotKey = wHotKey;
pLinkSettings->SetHotKey(dwHotKey);
dwHotKey = wHotKey;
pLinkSettings->SetHotKey(dwHotKey);
if (wszLinkTarget[0] != L'\0')
{
// guarantee null termination to make OACR happy.
wszLinkTarget[ARRAYSIZE(wszLinkTarget) - 1] = L'\0';
if (wszLinkTarget[0] != L'\0')
{
// guarantee null termination to make OACR happy.
wszLinkTarget[ARRAYSIZE(wszLinkTarget) - 1] = L'\0';
}
}
// if we got a title, use it. even on overall link value load failure, the title will be correct if

View file

@ -125,6 +125,13 @@ namespace Microsoft::Console::Render
COLORREF _lastBg;
bool _lastFontItalic;
// Memory pooling to save alloc/free work to the OS for things
// frequently created and dropped.
// It's important the pool is first so it can be given to the others on construction.
std::pmr::unsynchronized_pool_resource _pool;
std::pmr::vector<std::pmr::wstring> _polyStrings;
std::pmr::vector<std::pmr::basic_string<int>> _polyWidths;
[[nodiscard]] HRESULT _InvalidCombine(const RECT* const prc) noexcept;
[[nodiscard]] HRESULT _InvalidOffset(const POINT* const ppt) noexcept;
[[nodiscard]] HRESULT _InvalidRestrict() noexcept;

View file

@ -308,13 +308,11 @@ using namespace Microsoft::Console::Render;
const auto pPolyTextLine = &_pPolyText[_cPolyText];
auto pwsPoly = std::make_unique<wchar_t[]>(cchLine);
RETURN_IF_NULL_ALLOC(pwsPoly);
auto& polyString = _polyStrings.emplace_back(cchLine, UNICODE_NULL);
COORD const coordFontSize = _GetFontSize();
auto rgdxPoly = std::make_unique<int[]>(cchLine);
RETURN_IF_NULL_ALLOC(rgdxPoly);
auto& polyWidth = _polyWidths.emplace_back(cchLine, 0);
// Sum up the total widths the entire line/run is expected to take while
// copying the pixel widths into a structure to direct GDI how many pixels to use per character.
@ -327,9 +325,9 @@ using namespace Microsoft::Console::Render;
// Our GDI renderer hasn't and isn't going to handle things above U+FFFF or sequences.
// So replace anything complicated with a replacement character for drawing purposes.
pwsPoly[i] = cluster.GetTextAsSingle();
rgdxPoly[i] = gsl::narrow<int>(cluster.GetColumns()) * coordFontSize.X;
cchCharWidths += rgdxPoly[i];
polyString[i] = cluster.GetTextAsSingle();
polyWidth[i] = gsl::narrow<int>(cluster.GetColumns()) * coordFontSize.X;
cchCharWidths += polyWidth[i];
}
// Detect and convert for raster font...
@ -338,7 +336,7 @@ using namespace Microsoft::Console::Render;
// dispatch conversion into our codepage
// Find out the bytes required
int const cbRequired = WideCharToMultiByte(_fontCodepage, 0, pwsPoly.get(), (int)cchLine, nullptr, 0, nullptr, nullptr);
int const cbRequired = WideCharToMultiByte(_fontCodepage, 0, polyString.data(), (int)cchLine, nullptr, 0, nullptr, nullptr);
if (cbRequired != 0)
{
@ -346,7 +344,7 @@ using namespace Microsoft::Console::Render;
auto psConverted = std::make_unique<char[]>(cbRequired);
// Attempt conversion to current codepage
int const cbConverted = WideCharToMultiByte(_fontCodepage, 0, pwsPoly.get(), (int)cchLine, psConverted.get(), cbRequired, nullptr, nullptr);
int const cbConverted = WideCharToMultiByte(_fontCodepage, 0, polyString.data(), (int)cchLine, psConverted.get(), cbRequired, nullptr, nullptr);
// If successful...
if (cbConverted != 0)
@ -356,22 +354,22 @@ using namespace Microsoft::Console::Render;
if (cchRequired != 0)
{
auto pwsConvert = std::make_unique<wchar_t[]>(cchRequired);
std::pmr::wstring polyConvert(cchRequired, UNICODE_NULL, &_pool);
// Then do the actual conversion.
int const cchConverted = MultiByteToWideChar(CP_ACP, 0, psConverted.get(), cbRequired, pwsConvert.get(), cchRequired);
int const cchConverted = MultiByteToWideChar(CP_ACP, 0, psConverted.get(), cbRequired, polyConvert.data(), cchRequired);
if (cchConverted != 0)
{
// If all successful, use this instead.
pwsPoly.swap(pwsConvert);
polyString.swap(polyConvert);
}
}
}
}
}
pPolyTextLine->lpstr = pwsPoly.release();
pPolyTextLine->lpstr = polyString.data();
pPolyTextLine->n = gsl::narrow<UINT>(clusters.size());
pPolyTextLine->x = ptDraw.x;
pPolyTextLine->y = ptDraw.y;
@ -380,7 +378,7 @@ using namespace Microsoft::Console::Render;
pPolyTextLine->rcl.top = pPolyTextLine->y;
pPolyTextLine->rcl.right = pPolyTextLine->rcl.left + ((SHORT)cchCharWidths * coordFontSize.X);
pPolyTextLine->rcl.bottom = pPolyTextLine->rcl.top + coordFontSize.Y;
pPolyTextLine->pdx = rgdxPoly.release();
pPolyTextLine->pdx = polyWidth.data();
if (trimLeft)
{
@ -417,20 +415,10 @@ using namespace Microsoft::Console::Render;
hr = E_FAIL;
}
for (size_t iPoly = 0; iPoly < _cPolyText; iPoly++)
{
if (nullptr != _pPolyText[iPoly].lpstr)
{
delete[] _pPolyText[iPoly].lpstr;
_pPolyText[iPoly].lpstr = nullptr;
}
_polyStrings.clear();
_polyWidths.clear();
if (nullptr != _pPolyText[iPoly].pdx)
{
delete[] _pPolyText[iPoly].pdx;
_pPolyText[iPoly].pdx = nullptr;
}
}
ZeroMemory(_pPolyText, sizeof(_pPolyText));
_cPolyText = 0;
}

View file

@ -32,7 +32,10 @@ GdiEngine::GdiEngine() :
_lastFontItalic(false),
_fPaintStarted(false),
_hfont(nullptr),
_hfontItalic(nullptr)
_hfontItalic(nullptr),
_pool{}, // It's important the pool is first so it can be given to the others on construction.
_polyStrings{ &_pool },
_polyWidths{ &_pool }
{
ZeroMemory(_pPolyText, sizeof(POLYTEXTW) * s_cPolyTextCache);
_rcInvalid = { 0 };

View file

@ -35,7 +35,7 @@
{
Telemetry::Instance().LogApiCall(Telemetry::ApiCall::GetConsoleMode);
CONSOLE_MODE_MSG* const a = &m->u.consoleMsgL1.GetConsoleMode;
std::wstring handleType = L"unknown";
std::wstring_view handleType = L"unknown";
TraceLoggingWrite(g_hConhostV2EventTraceProvider,
"API_GetConsoleMode",
@ -54,14 +54,14 @@
RETURN_HR_IF_NULL(E_HANDLE, pObjectHandle);
if (pObjectHandle->IsInputHandle())
{
handleType = L"input handle";
handleType = L"input";
InputBuffer* pObj;
RETURN_IF_FAILED(pObjectHandle->GetInputBuffer(GENERIC_READ, &pObj));
m->_pApiRoutines->GetConsoleInputModeImpl(*pObj, a->Mode);
}
else
{
handleType = L"output handle";
handleType = L"output";
SCREEN_INFORMATION* pObj;
RETURN_IF_FAILED(pObjectHandle->GetScreenBuffer(GENERIC_READ, &pObj));
m->_pApiRoutines->GetConsoleOutputModeImpl(*pObj, a->Mode);

View file

@ -9,10 +9,17 @@
#include "DeviceComm.h"
_CONSOLE_API_MSG::_CONSOLE_API_MSG() :
Complete{ 0 },
State{ 0 },
_pDeviceComm(nullptr),
_pApiRoutines(nullptr)
_pApiRoutines(nullptr),
_inputBuffer{},
_outputBuffer{},
Descriptor{ 0 },
CreateObject{ 0 },
CreateScreenBuffer{ 0 },
msgHeader{ 0 }
{
ZeroMemory(this, sizeof(_CONSOLE_API_MSG));
}
ConsoleProcessHandle* _CONSOLE_API_MSG::GetProcessHandle() const
@ -57,6 +64,7 @@ ConsoleHandleData* _CONSOLE_API_MSG::GetObjectHandle() const
// - HRESULT indicating if the input buffer was successfully retrieved.
[[nodiscard]] HRESULT _CONSOLE_API_MSG::GetInputBuffer(_Outptr_result_bytebuffer_(*pcbSize) void** const ppvBuffer,
_Out_ ULONG* const pcbSize)
try
{
// Initialize the buffer if it hasn't been initialized yet.
if (State.InputBuffer == nullptr)
@ -65,12 +73,11 @@ ConsoleHandleData* _CONSOLE_API_MSG::GetObjectHandle() const
ULONG const cbReadSize = Descriptor.InputSize - State.ReadOffset;
wistd::unique_ptr<BYTE[]> pPayload = wil::make_unique_nothrow<BYTE[]>(cbReadSize);
RETURN_IF_NULL_ALLOC(pPayload);
_inputBuffer.resize(cbReadSize);
RETURN_IF_FAILED(ReadMessageInput(0, pPayload.get(), cbReadSize));
RETURN_IF_FAILED(ReadMessageInput(0, _inputBuffer.data(), cbReadSize));
State.InputBuffer = pPayload.release(); // TODO: MSFT: 9565140 - don't release, maintain as smart pointer.
State.InputBuffer = _inputBuffer.data();
State.InputBufferSize = cbReadSize;
}
@ -80,6 +87,7 @@ ConsoleHandleData* _CONSOLE_API_MSG::GetObjectHandle() const
return S_OK;
}
CATCH_RETURN();
// Routine Description:
// - This routine retrieves the output buffer associated with this message. It will allocate one if needed.
@ -94,6 +102,7 @@ ConsoleHandleData* _CONSOLE_API_MSG::GetObjectHandle() const
[[nodiscard]] HRESULT _CONSOLE_API_MSG::GetAugmentedOutputBuffer(const ULONG cbFactor,
_Outptr_result_bytebuffer_(*pcbSize) PVOID* const ppvBuffer,
_Out_ PULONG pcbSize)
try
{
// Initialize the buffer if it hasn't been initialized yet.
if (State.OutputBuffer == nullptr)
@ -103,11 +112,12 @@ ConsoleHandleData* _CONSOLE_API_MSG::GetObjectHandle() const
ULONG cbWriteSize = Descriptor.OutputSize - State.WriteOffset;
RETURN_IF_FAILED(ULongMult(cbWriteSize, cbFactor, &cbWriteSize));
BYTE* pPayload = new (std::nothrow) BYTE[cbWriteSize];
RETURN_IF_NULL_ALLOC(pPayload);
ZeroMemory(pPayload, sizeof(BYTE) * cbWriteSize);
_outputBuffer.resize(cbWriteSize);
State.OutputBuffer = pPayload; // TODO: MSFT: 9565140 - maintain as smart pointer.
// 0 it out.
std::fill(_outputBuffer.begin(), _outputBuffer.end(), (BYTE)0);
State.OutputBuffer = _outputBuffer.data();
State.OutputBufferSize = cbWriteSize;
}
@ -117,6 +127,7 @@ ConsoleHandleData* _CONSOLE_API_MSG::GetObjectHandle() const
return S_OK;
}
CATCH_RETURN();
// Routine Description:
// - This routine retrieves the output buffer associated with this message. It will allocate one if needed.
@ -148,8 +159,9 @@ ConsoleHandleData* _CONSOLE_API_MSG::GetObjectHandle() const
if (State.InputBuffer != nullptr)
{
delete[] static_cast<BYTE*>(State.InputBuffer);
_inputBuffer.clear();
State.InputBuffer = nullptr;
State.InputBufferSize = 0;
}
if (State.OutputBuffer != nullptr)
@ -165,8 +177,9 @@ ConsoleHandleData* _CONSOLE_API_MSG::GetObjectHandle() const
LOG_IF_FAILED(_pDeviceComm->WriteOutput(&IoOperation));
}
delete[] static_cast<BYTE*>(State.OutputBuffer);
_outputBuffer.clear();
State.OutputBuffer = nullptr;
State.OutputBufferSize = 0;
}
return hr;

View file

@ -35,6 +35,11 @@ typedef struct _CONSOLE_API_MSG
IDeviceComm* _pDeviceComm;
IApiRoutines* _pApiRoutines;
private:
boost::container::small_vector<BYTE, 128> _inputBuffer;
boost::container::small_vector<BYTE, 128> _outputBuffer;
public:
// From here down is the actual packet data sent/received.
CD_IO_DESCRIPTOR Descriptor;
union
@ -58,6 +63,10 @@ typedef struct _CONSOLE_API_MSG
// End packet data
public:
// DO NOT PUT MORE FIELDS DOWN HERE.
// The tail end of this structure will have a console driver packet
// copied over it and it will overwrite any fields declared here.
ConsoleProcessHandle* GetProcessHandle() const;
ConsoleHandleData* GetObjectHandle() const;
@ -73,4 +82,8 @@ public:
void SetReplyStatus(const NTSTATUS Status);
void SetReplyInformation(const ULONG_PTR pInformation);
// DO NOT PUT MORE FIELDS DOWN HERE.
// The tail end of this structure will have a console driver packet
// copied over it and it will overwrite any fields declared here.
} CONSOLE_API_MSG, *PCONSOLE_API_MSG, * const PCCONSOLE_API_MSG;