diff --git a/src/cascadia/TerminalApp/AppLogic.cpp b/src/cascadia/TerminalApp/AppLogic.cpp
index 106da0fbd..6b5b07bd0 100644
--- a/src/cascadia/TerminalApp/AppLogic.cpp
+++ b/src/cascadia/TerminalApp/AppLogic.cpp
@@ -189,7 +189,7 @@ namespace winrt::TerminalApp::implementation
}
AppLogic::AppLogic() :
- _reloadState{ std::chrono::milliseconds(100), []() { ApplicationState::SharedInstance().Reload(); } }
+ _reloadState{ std::chrono::milliseconds(100), []() { ApplicationState::SharedInstance().Reload(); ElevatedState::SharedInstance().Reload(); } }
{
// For your own sanity, it's better to do setup outside the ctor.
// If you do any setup in the ctor that ends up throwing an exception,
@@ -870,6 +870,7 @@ namespace winrt::TerminalApp::implementation
{
const std::filesystem::path settingsPath{ std::wstring_view{ CascadiaSettings::SettingsPath() } };
const std::filesystem::path statePath{ std::wstring_view{ ApplicationState::SharedInstance().FilePath() } };
+ // const std::filesystem::path elevatedStatePath{ std::wstring_view{ ElevatedState::SharedInstance().FilePath() } };
_reader.create(
settingsPath.parent_path().c_str(),
@@ -879,14 +880,14 @@ namespace winrt::TerminalApp::implementation
// editors, who will write a temp file, then rename it to be the
// actual file you wrote. So listen for that too.
wil::FolderChangeEvents::FileName | wil::FolderChangeEvents::LastWriteTime,
- [this, settingsBasename = settingsPath.filename(), stateBasename = statePath.filename()](wil::FolderChangeEvent, PCWSTR fileModified) {
+ [=](wil::FolderChangeEvent, PCWSTR fileModified) {
const auto modifiedBasename = std::filesystem::path{ fileModified }.filename();
- if (modifiedBasename == settingsBasename)
+ if (modifiedBasename == settingsPath.filename())
{
_reloadSettings->Run();
}
- else if (modifiedBasename == stateBasename)
+ else if (modifiedBasename == statePath.filename() /*|| modifiedBasename == elevatedStatePath.filename()*/)
{
_reloadState();
}
diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw
index f9e8cbf12..ad38d7a9b 100644
--- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw
+++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw
@@ -486,6 +486,18 @@
Warning
+
+ Cancel
+
+
+ You are about t execute the following commandline. {TODO! format this}. Do you wish to continue?
+
+
+ Allow Commandline
+
+
+ Warning
+
Type a command name...
diff --git a/src/cascadia/TerminalApp/TabManagement.cpp b/src/cascadia/TerminalApp/TabManagement.cpp
index 849bfcc69..ed1f40d3a 100644
--- a/src/cascadia/TerminalApp/TabManagement.cpp
+++ b/src/cascadia/TerminalApp/TabManagement.cpp
@@ -235,8 +235,44 @@ namespace winrt::TerminalApp::implementation
// - profile: profile settings for this connection
// - settings: the TerminalSettings object to use to create the TerminalControl with.
// - existingConnection: optionally receives a connection from the outside world instead of attempting to create one
- void TerminalPage::_CreateNewTabWithProfileAndSettings(const Profile& profile, const TerminalSettingsCreateResult& settings, TerminalConnection::ITerminalConnection existingConnection)
+ winrt::fire_and_forget TerminalPage::_CreateNewTabWithProfileAndSettings(Microsoft::Terminal::Settings::Model::Profile profile, Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult settings, TerminalConnection::ITerminalConnection existingConnection)
{
+ if (_isElevated())
+ {
+ auto cmdline{ settings.DefaultSettings().Commandline() };
+ auto allowedCommandlines{ ElevatedState::SharedInstance().AllowedCommandlines() };
+ bool commandlineWasAllowed = false;
+
+ if (allowedCommandlines)
+ {
+ for (const auto& approved : allowedCommandlines)
+ {
+ if (approved == cmdline)
+ {
+ commandlineWasAllowed = true;
+ break;
+ }
+ }
+ }
+ else
+ {
+ allowedCommandlines = winrt::single_threaded_vector();
+ }
+ if (!commandlineWasAllowed)
+ {
+ ContentDialogResult warningResult = co_await _ShowCommandlineApproveWarning();
+ if (warningResult != ContentDialogResult::Primary)
+ {
+ co_return;
+ }
+ else
+ {
+ allowedCommandlines.Append(cmdline);
+ }
+ ElevatedState::SharedInstance().AllowedCommandlines(allowedCommandlines);
+ }
+ }
+
// Initialize the new tab
// Create a connection based on the values in our settings object if we weren't given one.
auto connection = existingConnection ? existingConnection : _CreateConnectionFromSettings(profile, settings.DefaultSettings());
diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp
index 8ae486548..1f0f0d35f 100644
--- a/src/cascadia/TerminalApp/TerminalPage.cpp
+++ b/src/cascadia/TerminalApp/TerminalPage.cpp
@@ -49,6 +49,23 @@ namespace winrt
namespace winrt::TerminalApp::implementation
{
+ bool TerminalPage::_isElevated() const noexcept
+ {
+ // GH#2455 - Make sure to try/catch calls to Application::Current,
+ // because that _won't_ be an instance of TerminalApp::App in the
+ // LocalTests
+ try
+ {
+ // GH#3581 - There's a platform limitation that causes us to crash when we rearrange tabs.
+ // Xaml tries to send a drag visual (to wit: a screenshot) to the drag hosting process,
+ // but that process is running at a different IL than us.
+ // For now, we're disabling elevated drag.
+ return ::winrt::Windows::UI::Xaml::Application::Current().as<::winrt::TerminalApp::App>().Logic().IsElevated();
+ }
+ CATCH_LOG();
+ return false;
+ }
+
TerminalPage::TerminalPage() :
_tabs{ winrt::single_threaded_observable_vector() },
_mruTabs{ winrt::single_threaded_observable_vector() },
@@ -128,19 +145,7 @@ namespace winrt::TerminalApp::implementation
_tabView = _tabRow.TabView();
_rearranging = false;
- // GH#2455 - Make sure to try/catch calls to Application::Current,
- // because that _won't_ be an instance of TerminalApp::App in the
- // LocalTests
- auto isElevated = false;
- try
- {
- // GH#3581 - There's a platform limitation that causes us to crash when we rearrange tabs.
- // Xaml tries to send a drag visual (to wit: a screenshot) to the drag hosting process,
- // but that process is running at a different IL than us.
- // For now, we're disabling elevated drag.
- isElevated = ::winrt::Windows::UI::Xaml::Application::Current().as<::winrt::TerminalApp::App>().Logic().IsElevated();
- }
- CATCH_LOG();
+ const auto isElevated = _isElevated();
if (_settings.GlobalSettings().UseAcrylicInTabRow())
{
@@ -574,6 +579,15 @@ namespace winrt::TerminalApp::implementation
co_return ContentDialogResult::None;
}
+ winrt::Windows::Foundation::IAsyncOperation TerminalPage::_ShowCommandlineApproveWarning()
+ {
+ if (auto presenter{ _dialogPresenter.get() })
+ {
+ co_return co_await presenter.ShowDialog(FindName(L"ApproveCommandlineWarning").try_as());
+ }
+ co_return ContentDialogResult::None;
+ }
+
// Method Description:
// - Builds the flyout (dropdown) attached to the new tab button, and
// attaches it to the button. Populates the flyout with one entry per
diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h
index 0bdcf4aae..4c3ae8f8e 100644
--- a/src/cascadia/TerminalApp/TerminalPage.h
+++ b/src/cascadia/TerminalApp/TerminalPage.h
@@ -179,17 +179,19 @@ namespace winrt::TerminalApp::implementation
std::shared_ptr _windowIdToast{ nullptr };
std::shared_ptr _windowRenameFailedToast{ nullptr };
+ bool _isElevated() const noexcept;
void _ShowAboutDialog();
winrt::Windows::Foundation::IAsyncOperation _ShowCloseWarningDialog();
winrt::Windows::Foundation::IAsyncOperation _ShowCloseReadOnlyDialog();
winrt::Windows::Foundation::IAsyncOperation _ShowMultiLinePasteWarningDialog();
winrt::Windows::Foundation::IAsyncOperation _ShowLargePasteWarningDialog();
+ winrt::Windows::Foundation::IAsyncOperation _ShowCommandlineApproveWarning();
void _CreateNewTabFlyout();
void _OpenNewTabDropdown();
HRESULT _OpenNewTab(const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection = nullptr);
void _CreateNewTabFromPane(std::shared_ptr pane);
- void _CreateNewTabWithProfileAndSettings(const Microsoft::Terminal::Settings::Model::Profile& profile, const Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& settings, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection = nullptr);
+ winrt::fire_and_forget _CreateNewTabWithProfileAndSettings(Microsoft::Terminal::Settings::Model::Profile profile, Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult settings, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection = nullptr);
winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection _CreateConnectionFromSettings(Microsoft::Terminal::Settings::Model::Profile profile, Microsoft::Terminal::Settings::Model::TerminalSettings settings);
winrt::fire_and_forget _OpenNewWindow(const bool elevate, const Microsoft::Terminal::Settings::Model::NewTerminalArgs newTerminalArgs);
diff --git a/src/cascadia/TerminalApp/TerminalPage.xaml b/src/cascadia/TerminalApp/TerminalPage.xaml
index 35ac1807d..d7c37a70b 100644
--- a/src/cascadia/TerminalApp/TerminalPage.xaml
+++ b/src/cascadia/TerminalApp/TerminalPage.xaml
@@ -103,6 +103,11 @@
+
+