Skip to content

Commit 81cdb07

Browse files
authored
Separate pruning of elevated/unelevated session buffers (#19546)
Previously, launching an unelevated session after an elevated one would delete the latter's persisted buffers, and vice versa of course. Also, elevated buffers didn't have an ACL forbidding access to unelevated users. That's also fixed now. Closes #19526 ## Validation Steps Performed * Unelevated/elevated WT doesn't erase each other's buffers ✅ * Old buffers named `buffer_` are renamed to `elevated_` if needed ✅
1 parent 2537ea7 commit 81cdb07

File tree

20 files changed

+201
-93
lines changed

20 files changed

+201
-93
lines changed

.github/actions/spelling/expect/expect.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,6 +1139,7 @@ NOYIELD
11391139
NOZORDER
11401140
NPFS
11411141
nrcs
1142+
NRNW
11421143
NSTATUS
11431144
ntapi
11441145
ntdef

src/buffer/out/textBuffer.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2628,11 +2628,8 @@ void TextBuffer::_AppendRTFText(std::string& contentBuilder, const std::wstring_
26282628
}
26292629
}
26302630

2631-
void TextBuffer::SerializeToPath(const wchar_t* destination) const
2631+
void TextBuffer::SerializeTo(HANDLE handle) const
26322632
{
2633-
const wil::unique_handle file{ CreateFileW(destination, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr) };
2634-
THROW_LAST_ERROR_IF(!file);
2635-
26362633
static constexpr size_t writeThreshold = 32 * 1024;
26372634
std::wstring buffer;
26382635
buffer.reserve(writeThreshold + writeThreshold / 2);
@@ -2661,7 +2658,7 @@ void TextBuffer::SerializeToPath(const wchar_t* destination) const
26612658
{
26622659
const auto fileSize = gsl::narrow<DWORD>(buffer.size() * sizeof(wchar_t));
26632660
DWORD bytesWritten = 0;
2664-
THROW_IF_WIN32_BOOL_FALSE(WriteFile(file.get(), buffer.data(), fileSize, &bytesWritten, nullptr));
2661+
THROW_IF_WIN32_BOOL_FALSE(WriteFile(handle, buffer.data(), fileSize, &bytesWritten, nullptr));
26652662
THROW_WIN32_IF_MSG(ERROR_WRITE_FAULT, bytesWritten != fileSize, "failed to write");
26662663
buffer.clear();
26672664
}

src/buffer/out/textBuffer.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ class TextBuffer final
288288
const bool isIntenseBold,
289289
std::function<std::tuple<COLORREF, COLORREF, COLORREF>(const TextAttribute&)> GetAttributeColors) const noexcept;
290290

291-
void SerializeToPath(const wchar_t* destination) const;
291+
void SerializeTo(HANDLE handle) const;
292292

293293
struct PositionInformation
294294
{

src/cascadia/TerminalApp/IPaneContent.idl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ namespace TerminalApp
88
None,
99
Content,
1010
MovePane,
11-
PersistLayout,
12-
PersistAll
11+
Persist,
1312
};
1413

1514
runtimeclass BellEventArgs

src/cascadia/TerminalApp/TerminalPage.cpp

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2218,7 +2218,7 @@ namespace winrt::TerminalApp::implementation
22182218
}
22192219
}
22202220

2221-
void TerminalPage::PersistState(bool serializeBuffer)
2221+
void TerminalPage::PersistState()
22222222
{
22232223
// This method may be called for a window even if it hasn't had a tab yet or lost all of them.
22242224
// We shouldn't persist such windows.
@@ -2233,7 +2233,7 @@ namespace winrt::TerminalApp::implementation
22332233
for (auto tab : _tabs)
22342234
{
22352235
auto t = winrt::get_self<implementation::Tab>(tab);
2236-
auto tabActions = t->BuildStartupActions(serializeBuffer ? BuildStartupKind::PersistAll : BuildStartupKind::PersistLayout);
2236+
auto tabActions = t->BuildStartupActions(BuildStartupKind::Persist);
22372237
actions.insert(actions.end(), std::make_move_iterator(tabActions.begin()), std::make_move_iterator(tabActions.end()));
22382238
}
22392239

@@ -2319,6 +2319,29 @@ namespace winrt::TerminalApp::implementation
23192319
CloseWindowRequested.raise(*this, nullptr);
23202320
}
23212321

2322+
std::vector<IPaneContent> TerminalPage::Panes() const
2323+
{
2324+
std::vector<IPaneContent> panes;
2325+
2326+
for (const auto tab : _tabs)
2327+
{
2328+
const auto impl = _GetTabImpl(tab);
2329+
if (!impl)
2330+
{
2331+
continue;
2332+
}
2333+
2334+
impl->GetRootPane()->WalkTree([&](auto&& pane) {
2335+
if (auto content = pane->GetContent())
2336+
{
2337+
panes.push_back(std::move(content));
2338+
}
2339+
});
2340+
}
2341+
2342+
return panes;
2343+
}
2344+
23222345
// Method Description:
23232346
// - Move the viewport of the terminal of the currently focused tab up or
23242347
// down a number of lines.
@@ -3527,9 +3550,12 @@ namespace winrt::TerminalApp::implementation
35273550

35283551
if (hasSessionId)
35293552
{
3553+
using namespace std::string_view_literals;
3554+
35303555
const auto settingsDir = CascadiaSettings::SettingsDirectory();
3531-
const auto idStr = Utils::GuidToPlainString(sessionId);
3532-
const auto path = fmt::format(FMT_COMPILE(L"{}\\buffer_{}.txt"), settingsDir, idStr);
3556+
const auto admin = IsRunningElevated();
3557+
const auto filenamePrefix = admin ? L"elevated_"sv : L"buffer_"sv;
3558+
const auto path = fmt::format(FMT_COMPILE(L"{}\\{}{}.txt"), settingsDir, filenamePrefix, sessionId);
35333559
control.RestoreFromPath(path);
35343560
}
35353561

src/cascadia/TerminalApp/TerminalPage.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ namespace winrt::TerminalApp::implementation
122122

123123
safe_void_coroutine RequestQuit();
124124
safe_void_coroutine CloseWindow();
125-
void PersistState(bool serializeBuffer);
125+
void PersistState();
126+
std::vector<IPaneContent> Panes() const;
126127

127128
void ToggleFocusMode();
128129
void ToggleFullscreen();

src/cascadia/TerminalApp/TerminalPaneContent.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -140,22 +140,16 @@ namespace winrt::TerminalApp::implementation
140140
// "attach existing" rather than a "create"
141141
args.ContentId(_control.ContentId());
142142
break;
143-
case BuildStartupKind::PersistAll:
143+
case BuildStartupKind::Persist:
144144
{
145145
const auto connection = _control.Connection();
146146
const auto id = connection ? connection.SessionId() : winrt::guid{};
147-
148147
if (id != winrt::guid{})
149148
{
150-
const auto settingsDir = CascadiaSettings::SettingsDirectory();
151-
const auto idStr = ::Microsoft::Console::Utils::GuidToPlainString(id);
152-
const auto path = fmt::format(FMT_COMPILE(L"{}\\buffer_{}.txt"), settingsDir, idStr);
153-
_control.PersistToPath(path);
154149
args.SessionId(id);
155150
}
156151
break;
157152
}
158-
case BuildStartupKind::PersistLayout:
159153
default:
160154
break;
161155
}

src/cascadia/TerminalApp/TerminalWindow.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,11 +253,11 @@ namespace winrt::TerminalApp::implementation
253253
AppLogic::Current()->NotifyRootInitialized();
254254
}
255255

256-
void TerminalWindow::PersistState(bool serializeBuffer)
256+
void TerminalWindow::PersistState()
257257
{
258258
if (_root)
259259
{
260-
_root->PersistState(serializeBuffer);
260+
_root->PersistState();
261261
}
262262
}
263263

@@ -830,6 +830,11 @@ namespace winrt::TerminalApp::implementation
830830
return _root.as<winrt::Windows::UI::Xaml::Controls::Control>();
831831
}
832832

833+
winrt::Windows::Foundation::Collections::IVector<IPaneContent> TerminalWindow::Panes() const
834+
{
835+
return winrt::single_threaded_vector(_root->Panes());
836+
}
837+
833838
// Method Description:
834839
// - Gets the title of the currently focused terminal control. If there
835840
// isn't a control selected for any reason, returns "Terminal"

src/cascadia/TerminalApp/TerminalWindow.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ namespace winrt::TerminalApp::implementation
7171

7272
void Create();
7373

74-
void PersistState(bool serializeBuffer);
74+
void PersistState();
7575

7676
void UpdateSettings(winrt::TerminalApp::SettingsLoadEventArgs args);
7777

@@ -111,6 +111,7 @@ namespace winrt::TerminalApp::implementation
111111
float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const;
112112

113113
Windows::UI::Xaml::UIElement GetRoot() noexcept;
114+
winrt::Windows::Foundation::Collections::IVector<IPaneContent> Panes() const;
114115

115116
hstring Title();
116117
void TitlebarClicked();

src/cascadia/TerminalApp/TerminalWindow.idl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT license.
33

4+
import "IPaneContent.idl";
45
import "TerminalPage.idl";
56
import "ShortcutActionDispatch.idl";
67

@@ -59,9 +60,10 @@ namespace TerminalApp
5960
Boolean ShouldImmediatelyHandoffToElevated();
6061
void HandoffToElevated();
6162

62-
void PersistState(Boolean serializeBuffer);
63+
void PersistState();
6364

6465
Windows.UI.Xaml.UIElement GetRoot();
66+
IVector<IPaneContent> Panes { get; };
6567

6668
String Title { get; };
6769
Boolean FocusMode { get; };

0 commit comments

Comments
 (0)