Merge remote-tracking branch 'origin/main' into dev/migrie/f/remoting.dll
This commit is contained in:
commit
88ffc6fc0e
|
@ -59,6 +59,7 @@ OUTLINETEXTMETRICW
|
|||
overridable
|
||||
PAGESCROLL
|
||||
REGCLS
|
||||
pmr
|
||||
RETURNCMD
|
||||
rfind
|
||||
roundf
|
||||
|
|
14
.github/actions/spell-check/expect/a129ff14ec985d6b7bf09e296a831c955d41040b.txt
vendored
Normal file
14
.github/actions/spell-check/expect/a129ff14ec985d6b7bf09e296a831c955d41040b.txt
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
checkboxes
|
||||
CSIDL
|
||||
csv
|
||||
horiz
|
||||
IDispatch
|
||||
inlines
|
||||
IWeb
|
||||
Progman
|
||||
reserialize
|
||||
SHANDLE
|
||||
SHGFP
|
||||
udk
|
||||
unfocus
|
||||
WClass
|
40
.github/actions/spell-check/expect/expect.txt
vendored
40
.github/actions/spell-check/expect/expect.txt
vendored
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -15,7 +15,6 @@ Author(s):
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "boost/container/small_vector.hpp"
|
||||
#include "TextAttribute.hpp"
|
||||
#include "TextAttributeRun.hpp"
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ Revision History:
|
|||
#include "CharRowCellReference.hpp"
|
||||
#include "CharRowCell.hpp"
|
||||
#include "UnicodeStorage.hpp"
|
||||
#include "boost/container/small_vector.hpp"
|
||||
|
||||
class ROW;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -81,6 +81,5 @@
|
|||
<AdditionalDependencies>$(OpenConsoleCommonOutDir)\conptylib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
|
||||
</Project>
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue