Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions SampleApps/WebView2APISample/AppWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#include "ScenarioServiceWorkerPostMessage.h"
#include "ScenarioServiceWorkerPostMessageSetting.h"
#include "ScenarioSharedWorkerManager.h"
#include "ScenarioOriginConfigurationAPI.h"
#include "ScenarioSaveAs.h"
#include "ScenarioScreenCapture.h"
#include "ScenarioSensitivityLabel.h"
Expand Down Expand Up @@ -833,6 +834,20 @@ bool AppWindow::ExecuteWebViewCommands(WPARAM wParam, LPARAM lParam)
component->ToggleServiceWorkerJsApiSetting();
return true;
}
case IDM_SCENARIO_SET_ORIGIN_FEATURES:
{
auto* const trustedOriginComponent =
GetOrCreateComponent<ScenarioOriginConfigurationAPI>();
trustedOriginComponent->SetOriginFeatures();
return true;
}
case IDM_SCENARIO_GET_ORIGIN_FEATURES:
{
auto* const trustedOriginComponent =
GetOrCreateComponent<ScenarioOriginConfigurationAPI>();
trustedOriginComponent->GetOriginFeatures();
return true;
}
case IDM_SCENARIO_SCREEN_CAPTURE:
{
NewComponent<ScenarioScreenCapture>(this);
Expand Down
66 changes: 65 additions & 1 deletion SampleApps/WebView2APISample/ProcessComponent.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (C) Microsoft Corporation. All rights reserved.
// Copyright (C) Microsoft Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

Expand Down Expand Up @@ -121,6 +121,70 @@ ProcessComponent::ProcessComponent(AppWindow* appWindow)
<< L"Process description: " << processDescription.get() << std::endl
<< (failedModule ? L"Failed module: " : L"")
<< (failedModule ? failedModule.get() : L"");

//! [CrashReport]
// Query for the crash report (available when Crashpad handled
// the crash; nullptr for __fastfail / WER-only crashes).
auto experimentalArgs2 =
args.try_query<ICoreWebView2ExperimentalProcessFailedEventArgs2>();
if (experimentalArgs2)
{
wil::com_ptr<ICoreWebView2ExperimentalCrashReport> crashReport;
CHECK_FAILURE(experimentalArgs2->get_CrashReport(&crashReport));
if (crashReport)
{
wil::unique_cotaskmem_string crashReportId;
if (SUCCEEDED(crashReport->get_CrashReportId(&crashReportId)) &&
crashReportId)
{
message << L"\nCrash Report ID: " << crashReportId.get();
}

UINT32 exceptionCode;
if (SUCCEEDED(crashReport->get_ExceptionCode(&exceptionCode)))
{
message << L"\nException Code: 0x" << std::hex << exceptionCode
<< std::dec;
}

wil::unique_cotaskmem_string faultingModuleName;
if (SUCCEEDED(
crashReport->get_FaultingModuleName(&faultingModuleName)) &&
faultingModuleName)
{
message << L"\nFaulting Module: " << faultingModuleName.get();
}

wil::unique_cotaskmem_string faultingModuleVersion;
if (SUCCEEDED(crashReport->get_FaultingModuleVersion(
&faultingModuleVersion)) &&
faultingModuleVersion)
{
message << L"\nModule Version: " << faultingModuleVersion.get();
}

UINT64 faultOffset;
if (SUCCEEDED(crashReport->get_FaultOffset(&faultOffset)))
{
message << L"\nFault Offset: 0x" << std::hex << faultOffset
<< std::dec;
}

wil::unique_cotaskmem_string bucketId;
if (SUCCEEDED(crashReport->get_BucketId(&bucketId)) && bucketId)
{
message << L"\nCrash Bucket: " << bucketId.get();
}

UINT64 reportTime;
if (SUCCEEDED(crashReport->get_ReportTime(&reportTime)))
{
message << L"\nReport Time: " << reportTime;
}
}
}
//! [CrashReport]

m_appWindow->AsyncMessageBox( std::move(message.str()), L"Child process failed");
}
return S_OK;
Expand Down
194 changes: 194 additions & 0 deletions SampleApps/WebView2APISample/ScenarioOriginConfigurationAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,197 @@
#include "CheckFailure.h"
#include "TextInputDialog.h"
#include "Util.h"

#include "ScenarioOriginConfigurationAPI.h"

using namespace Microsoft::WRL;

static constexpr int kEnhancedSecurityModeValue = 1;
static constexpr int kSmartScreenValue = 2;

ScenarioOriginConfigurationAPI::ScenarioOriginConfigurationAPI(AppWindow* appWindow)
: m_appWindow(appWindow)
{
CHECK_FAILURE(m_appWindow ? S_OK : E_POINTER);
wil::com_ptr<ICoreWebView2> webView = m_appWindow->GetWebView();
CHECK_FAILURE(webView ? S_OK : E_POINTER);
auto webView2_13 = webView.try_query<ICoreWebView2_13>();
CHECK_FAILURE(webView2_13 ? S_OK : E_POINTER);
CHECK_FAILURE(webView2_13->get_Profile(&m_webviewProfile));
}

ScenarioOriginConfigurationAPI::~ScenarioOriginConfigurationAPI() = default;

std::wstring ScenarioOriginConfigurationAPI::FeatureToString(
COREWEBVIEW2_ORIGIN_FEATURE feature)
{
switch (feature)
{
case COREWEBVIEW2_ORIGIN_FEATURE_ENHANCED_SECURITY_MODE:
return L"EnhancedSecurityMode";
case COREWEBVIEW2_ORIGIN_FEATURE_REPUTATION_CHECKING:
return L"ReputationChecking";
default:
return L"Unknown";
}
}

void ScenarioOriginConfigurationAPI::SetFeatureForOrigins(
const std::vector<std::wstring>& originPatterns,
const std::vector<
std::pair<COREWEBVIEW2_ORIGIN_FEATURE, COREWEBVIEW2_ORIGIN_FEATURE_STATE>>& features)
{
auto experimentalProfile16 =
m_webviewProfile.try_query<ICoreWebView2ExperimentalProfile16>();
CHECK_FEATURE_RETURN_EMPTY(experimentalProfile16);

// featureSettings holds wil::com_ptr for COM lifetime management (keeps refcount > 0).
// featureSettingsRaw holds raw pointers extracted from featureSettings to pass to the API.
// Both are needed because the API requires a pointer array, but we need smart pointers to
// prevent premature COM object destruction.
std::vector<wil::com_ptr<ICoreWebView2ExperimentalOriginFeatureSetting>> featureSettings;
std::vector<ICoreWebView2ExperimentalOriginFeatureSetting*> featureSettingsRaw;

for (const auto& [featureKind, featureState] : features)
{
wil::com_ptr<ICoreWebView2ExperimentalOriginFeatureSetting> setting;
CHECK_FAILURE(experimentalProfile16->CreateOriginFeatureSetting(
featureKind, featureState, &setting));
featureSettings.push_back(setting);
featureSettingsRaw.push_back(setting.get());
}

std::vector<LPCWSTR> origins;
for (const auto& pattern : originPatterns)
{
origins.push_back(pattern.c_str());
}

CHECK_FAILURE(experimentalProfile16->SetOriginFeatures(
static_cast<UINT32>(origins.size()), origins.data(),
static_cast<UINT32>(featureSettingsRaw.size()), featureSettingsRaw.data()));
}

void ScenarioOriginConfigurationAPI::GetOriginFeatures()
{
auto experimentalProfile16 =
m_webviewProfile.try_query<ICoreWebView2ExperimentalProfile16>();
CHECK_FEATURE_RETURN_EMPTY(experimentalProfile16);

TextInputDialog inputDialog(
m_appWindow->GetMainWindow(), L"Get Trusted Origin Features",
L"Enter the origin to retrieve feature settings for:", L"Origin:",
std::wstring(L"https://www.microsoft.com"),
false); // not read-only

if (inputDialog.confirmed)
{
std::wstring origin = inputDialog.input;

CHECK_FAILURE(experimentalProfile16->GetEffectiveFeaturesForOrigin(
origin.c_str(),
Callback<ICoreWebView2ExperimentalGetEffectiveFeaturesForOriginCompletedHandler>(
[appWindow = m_appWindow, origin](
HRESULT errorCode,
ICoreWebView2ExperimentalOriginFeatureSettingCollectionView* result)
-> HRESULT
{
if (SUCCEEDED(errorCode))
{
UINT32 count = 0;
CHECK_FAILURE(result->get_Count(&count));

std::wstring message = L"Features for origin: " + origin + L"\n";
for (UINT32 i = 0; i < count; i++)
{
wil::com_ptr<ICoreWebView2ExperimentalOriginFeatureSetting> setting;
CHECK_FAILURE(result->GetValueAtIndex(i, &setting));

COREWEBVIEW2_ORIGIN_FEATURE feature;
COREWEBVIEW2_ORIGIN_FEATURE_STATE featureState;
CHECK_FAILURE(setting->get_Feature(&feature));
CHECK_FAILURE(setting->get_State(&featureState));

message +=
L"Feature: " + FeatureToString(feature) + L", Enabled: " +
(featureState == COREWEBVIEW2_ORIGIN_FEATURE_STATE_ENABLED
? L"True"
: L"False") +
L"\n";
}

MessageBoxW(
appWindow->GetMainWindow(), message.c_str(),
L"Trusted Origin Features", MB_OK);
}
else
{
ShowFailure(
errorCode,
L"Failed to get effective features for origin: " + origin);
}
return S_OK;
})
.Get()));
}
}

void ScenarioOriginConfigurationAPI::SetOriginFeatures()
{
static constexpr wchar_t kOriginPatternsLabel[] = L"Enter origin patterns separated with ;";
static constexpr wchar_t kFeaturesGroupLabel[] = L"Select features to enable:";

// Builder with text area for origin input and checkbox for feature selection.
auto enhancedDialog =
TextInputDialog::Builder(
m_appWindow->GetMainWindow(), L"Configure Trusted Origin",
L"Trusted Origin Configuration:")
.AddTextArea(kOriginPatternsLabel, L"https://www.microsoft.com")
.AddCheckBoxGroup(
kFeaturesGroupLabel,
{{L"Enable Enhanced Security Mode", kEnhancedSecurityModeValue, true},
{L"Disable Reputation Checking", kSmartScreenValue, false}})
.Build();

if (enhancedDialog.confirmed)
{
// Retrieve the origin text area. Skip if the control is missing.
auto textAreaIt = enhancedDialog.results.find(kOriginPatternsLabel);
if (textAreaIt == enhancedDialog.results.end())
return;
auto& textArea = std::get<TextArea>(textAreaIt->second);
std::wstring input = textArea.input;

// Retrieve the feature checkbox group. Skip if the control is missing.
std::vector<std::pair<COREWEBVIEW2_ORIGIN_FEATURE, COREWEBVIEW2_ORIGIN_FEATURE_STATE>>
features;
auto groupIt = enhancedDialog.results.find(kFeaturesGroupLabel);
if (groupIt == enhancedDialog.results.end())
return;
auto& group = std::get<CheckBoxGroup>(groupIt->second);
for (const auto& option : group.options)
{
if (option.isSelected && option.value == kEnhancedSecurityModeValue)
{
features.push_back(
{COREWEBVIEW2_ORIGIN_FEATURE_ENHANCED_SECURITY_MODE,
COREWEBVIEW2_ORIGIN_FEATURE_STATE_ENABLED});
}
if (option.isSelected && option.value == kSmartScreenValue)
{
// Disabling SmartScreen for the origin = allow-listing it.
features.push_back(
{COREWEBVIEW2_ORIGIN_FEATURE_REPUTATION_CHECKING,
COREWEBVIEW2_ORIGIN_FEATURE_STATE_DISABLED});
}
}

std::vector<std::wstring> origins = Util::SplitString(input, L';');

// Set features for all origins in a single call.
if (!features.empty())
{
SetFeatureForOrigins(origins, features);
}
}
}
28 changes: 28 additions & 0 deletions SampleApps/WebView2APISample/ScenarioOriginConfigurationAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,31 @@
// found in the LICENSE file.

#pragma once

#include <string>
#include <vector>

#include "AppWindow.h"
#include "ComponentBase.h"

// Demonstrates configuring trusted origins via WebView2 profile.
class ScenarioOriginConfigurationAPI : public ComponentBase
{
public:
ScenarioOriginConfigurationAPI(AppWindow* appWindow);
~ScenarioOriginConfigurationAPI() override;

void SetFeatureForOrigins(
const std::vector<std::wstring>& originPattern,
const std::vector<
std::pair<COREWEBVIEW2_ORIGIN_FEATURE, COREWEBVIEW2_ORIGIN_FEATURE_STATE>>&
features);
void GetOriginFeatures();
void SetOriginFeatures();

private:
static std::wstring FeatureToString(COREWEBVIEW2_ORIGIN_FEATURE feature);

AppWindow* const m_appWindow; // Non-owning, guaranteed non-null.
wil::com_ptr<ICoreWebView2Profile> m_webviewProfile;
};
5 changes: 5 additions & 0 deletions SampleApps/WebView2APISample/WebView2APISample.rc
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,11 @@ BEGIN
MENUITEM "Toggle Suppress Default Find Dialog", IDC_SUPPRESS_DEFAULT_FIND_DIALOG
MENUITEM "Toggle Should Match Word", IDC_SHOULD_MATCH_WHOLE_WORD
END
POPUP "Origin Configuration for Features"
BEGIN
MENUITEM "Set Feature Settings For Origins", IDM_SCENARIO_SET_ORIGIN_FEATURES
MENUITEM "Get Feature Settings For Origins", IDM_SCENARIO_GET_ORIGIN_FEATURES
END
POPUP "Sensitivity Label"
BEGIN
MENUITEM "Set PIRM Allowlist", IDM_SCENARIO_PIRM_SET_ALLOWLIST
Expand Down
4 changes: 2 additions & 2 deletions SampleApps/WebView2APISample/WebView2APISample.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -536,13 +536,13 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
<Import Project="..\packages\Microsoft.Web.WebView2.1.0.4071-prerelease\build\native\Microsoft.Web.WebView2.targets" Condition="Exists('..\packages\Microsoft.Web.WebView2.1.0.4071-prerelease\build\native\Microsoft.Web.WebView2.targets')" />
<Import Project="..\packages\Microsoft.Web.WebView2.1.0.4126-prerelease\build\native\Microsoft.Web.WebView2.targets" Condition="Exists('..\packages\Microsoft.Web.WebView2.1.0.4126-prerelease\build\native\Microsoft.Web.WebView2.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.Web.WebView2.1.0.4071-prerelease\build\native\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Web.WebView2.1.0.4071-prerelease\build\native\Microsoft.Web.WebView2.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.Web.WebView2.1.0.4126-prerelease\build\native\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Web.WebView2.1.0.4126-prerelease\build\native\Microsoft.Web.WebView2.targets'))" />
</Target>
</Project>
2 changes: 1 addition & 1 deletion SampleApps/WebView2APISample/packages.config
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Web.WebView2" version="1.0.4071-prerelease" targetFramework="native" />
<package id="Microsoft.Web.WebView2" version="1.0.4126-prerelease" targetFramework="native" />
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.220201.1" targetFramework="native" />
</packages>
2 changes: 2 additions & 0 deletions SampleApps/WebView2APISample/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@
#define IDM_SCENARIO_SERVICE_WORKER_POST_MESSAGE 3010
#define IDM_SCENARIO_WEBRTC_UDP_PORT_CONFIGURATION 3011
#define IDM_TOGGLE_SERVICE_WORKER_JS_API_SETTING 3012
#define IDM_SCENARIO_SET_ORIGIN_FEATURES 3013
#define IDM_SCENARIO_GET_ORIGIN_FEATURES 3014
// Base ID for dynamically created controls in TextInputDialog.
// IDs 5000-5099 are reserved for dynamic controls (10 groups x 10 options).
#define IDC_DYNAMIC_CONTROL_BASE 5000
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.4071-prerelease" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.4126-prerelease" />
</ItemGroup>
<ItemGroup>
<Folder Include="assets\" />
Expand Down
Loading
Loading