From 2544d98304f269be8e639dfe9d78b9d78becd05b Mon Sep 17 00:00:00 2001 From: Eain C <41822980+Master-Ukulele@users.noreply.github.com> Date: Tue, 19 Mar 2024 16:32:43 -0700 Subject: [PATCH 1/9] Create DangerousFileSecurityDialog.md --- specs/DangerousFileSecurityDialog.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 specs/DangerousFileSecurityDialog.md diff --git a/specs/DangerousFileSecurityDialog.md b/specs/DangerousFileSecurityDialog.md new file mode 100644 index 000000000..5d959b4aa --- /dev/null +++ b/specs/DangerousFileSecurityDialog.md @@ -0,0 +1,27 @@ +Dangerous File Security Dialog API +=== + +# Background + +# Description + +# Examples +## Win32 C++ +### +```c++ + +``` + +## .Net/ WinRT +### +```c# +``` + +# API Details +## Win32 C++ +```c++ +``` + +## .Net/ WinRT +```c# (but really MIDL3) +``` From 3e68a0b4410aad2fe048f66851107792d25f15d2 Mon Sep 17 00:00:00 2001 From: Eain C <41822980+Master-Ukulele@users.noreply.github.com> Date: Wed, 17 Apr 2024 16:33:29 -0700 Subject: [PATCH 2/9] Add descriptions and win32 codes --- specs/DangerousFileSecurityDialog.md | 27 ----- specs/FileTypePolicy.md | 163 +++++++++++++++++++++++++++ 2 files changed, 163 insertions(+), 27 deletions(-) delete mode 100644 specs/DangerousFileSecurityDialog.md create mode 100644 specs/FileTypePolicy.md diff --git a/specs/DangerousFileSecurityDialog.md b/specs/DangerousFileSecurityDialog.md deleted file mode 100644 index 5d959b4aa..000000000 --- a/specs/DangerousFileSecurityDialog.md +++ /dev/null @@ -1,27 +0,0 @@ -Dangerous File Security Dialog API -=== - -# Background - -# Description - -# Examples -## Win32 C++ -### -```c++ - -``` - -## .Net/ WinRT -### -```c# -``` - -# API Details -## Win32 C++ -```c++ -``` - -## .Net/ WinRT -```c# (but really MIDL3) -``` diff --git a/specs/FileTypePolicy.md b/specs/FileTypePolicy.md new file mode 100644 index 000000000..23f7c8383 --- /dev/null +++ b/specs/FileTypePolicy.md @@ -0,0 +1,163 @@ +File Type Policy API +=== + +# Background +When saving a file with original SaveFilePicker, a security alert might be +prompted, because the browser applies the [file type policies](https://learn.microsoft.com/en-us/deployedge/microsoft-edge-security-downloads-interruptions#file-types-requiring-a-gesture) +to protect end users. However, in a WebView2 build App, when end users try +to save a file with a certain file extension, they usually can trust the +host App, domain and file extension. So, we provide the App developers the +File Type Policy API to manage the file type policies dynamically. + +We'd appreciate your feedback. + +# Description + +We proposed the `CoreWebView2.FileTypePolicyChecking` event. You can register +this event to get the file path, file extension and domain uri information, +when end users try to save a file from your App. Then you can apply your own +rules to allow save the file with, or without a default warning dialog; +to cancel the saving; and even to create your own UI to manage runtime +file type policies. + +# Examples +## Win32 C++ +This example shows suppressing file type policy, security dialog, and +allow to save the file directly. It also blocks saving the exe file. +The sample code will register the event with custom rules. +```c++ +bool ScenarioFileTypePolicyStaging::AddCustomFileTypePolicies() +{ + if (!m_webView2Staging25) + return false; + // Register a handler for the `FileTypePolicyChecking` event. + m_webView2Staging25->add_FileTypePolicyChecking( + Callback( + [this]( + ICoreWebView2* sender, + ICoreWebView2StagingFileTypePolicyCheckingEventArgs* args) -> HRESULT + { + LPWSTR extension; + // Get the file extension for file to be saved. + CHECK_FAILURE(args->get_FileExtension(&extension)); + // Create your own rules of file type policy. + if (lstrcmpW(extension, L"eml") == 0) + // Set the `SuppressDefaultPolicy` property to skip the default + // file type policy checking and a possible security alert dialog. + // + // This will consent to save the file. + CHECK_FAILURE(args->put_SuppressDefaultPolicy(TRUE)); + if (lstrcmpW(extension, L"exe") == 0) + // Set the `Cancel` property to cancel the saving directly. + // + // This will abort to save the file. + CHECK_FAILURE(args->put_Cancel(TRUE)); + wil::com_ptr deferral; + CHECK_FAILURE(args->GetDeferral(&deferral)); + + m_appWindow->RunAsync([deferral]() { CHECK_FAILURE(deferral->Complete()); }); + + return S_OK; + }) + .Get(), + &m_fileTypePolicyCheckingToken); + return true; +} +``` + +## .Net/ WinRT +### +```c# +``` + +# API Details +## Win32 C++ +```c++ +interface ICoreWebView2 : IUnknown { + /// Adds an event handler for the `FileTypePolicyChecking` event. + /// This event will be raised during system FileTypePolicy + /// checking the dangerous file extension list. + /// + /// Developers can specify their own decision on if allow this file + /// type extension to be saved, or downloaded. Here are two properties + /// in `ICoreWebView2FileTypePolicyCheckingEventArgs` to manage the + /// decision, `Cancel` and `SuppressDefaultPolicy`. + /// Table of Properties' value and result: + /// + /// | Cancel | SuppressDefaultPolicy | Result + /// | ------ | ------ | --------------------- + /// | False | False | Process to default policy check. It might show + /// | | | security warning UI if the file extension is + /// | | | dangerous. + /// | ------ | ------ | --------------------- + /// | False | True | Skip the default policy check and the possible + /// | | | security warning. Start saving or downloading. + /// | ------ | ------ | --------------------- + /// | True | T or F | Skip the default policy check and the possible + /// | | | security warning. Abort save or download. + HRESULT add_FileTypePolicyChecking( + [in] ICoreWebView2StagingFileTypePolicyCheckingEventHandler* eventHandler, + [out] EventRegistrationToken* token); + + /// Removes an event handler previously added with `add_FileTypePolicyChecking`. + HRESULT remove_FileTypePolicyChecking( + [in] EventRegistrationToken token); +} + + +/// The event args for `FileTypePolicyChecking` event. +interface ICoreWebView2StagingFileTypePolicyCheckingEventArgs : IUnknown { + /// Gets the `Cancel` property. + [propget] HRESULT Cancel([out, retval] BOOL* value); + + /// Set if cancel the upcoming save/download. `TRUE` means the action + /// will be cancelled before validations in default policy. + /// + /// The default value is `FALSE`. + [propput] HRESULT Cancel([in] BOOL value); + + /// Get the extension of file to be saved. + /// + /// File extension can be empty. + /// + /// Only final extension will be provided. For example, "*.tar.gz" + /// is a double extension, where the "gz" will be its final extension. + /// + /// File extension usage in the API is case sensitive. + [propget] HRESULT FileExtension([out, retval] LPWSTR* value); + + /// Get the full path of file to be saved. This includes the + /// file name and extension. + [propget] HRESULT FilePath([out, retval] LPWSTR* value); + + /// Gets the `SuppressDefaultPolicy` property. + [propget] HRESULT SuppressDefaultPolicy([out, retval] BOOL* value); + + /// Set if the default policy checking and security warning will be + /// suppressed. `TRUE` means it will be suppressed. + /// + /// The default value is `FALSE`. + [propput] HRESULT SuppressDefaultPolicy([in] BOOL value); + + /// Get the uri of file source. + [propget] HRESULT Uri([out, retval] LPWSTR* value); + + /// Returns an `ICoreWebView2Deferral` object. Use this operation to complete + /// the FileTypePolicyCheckingEvent. + HRESULT GetDeferral( + [out, retval] ICoreWebView2Deferral** value + ); +} + +/// Receives `FileTypePolicyChecking` events. +interface ICoreWebView2StagingFileTypePolicyCheckingEventHandler : IUnknown { + /// Provides the event args for the corresponding event. + HRESULT Invoke( + [in] ICoreWebView2* sender, + [in] ICoreWebView2StagingFileTypePolicyCheckingEventArgs* args); +} +``` + +## .Net/ WinRT +```c# (but really MIDL3) +``` From 41c21cc925f2cdbd2222cae7a42ca2bff1e6d990 Mon Sep 17 00:00:00 2001 From: Eain C <41822980+Master-Ukulele@users.noreply.github.com> Date: Thu, 18 Apr 2024 15:55:53 -0700 Subject: [PATCH 3/9] Add .net/winrt details, update the description. --- specs/FileTypePolicy.md | 82 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 10 deletions(-) diff --git a/specs/FileTypePolicy.md b/specs/FileTypePolicy.md index 23f7c8383..4691f77c0 100644 --- a/specs/FileTypePolicy.md +++ b/specs/FileTypePolicy.md @@ -37,20 +37,20 @@ bool ScenarioFileTypePolicyStaging::AddCustomFileTypePolicies() ICoreWebView2* sender, ICoreWebView2StagingFileTypePolicyCheckingEventArgs* args) -> HRESULT { - LPWSTR extension; // Get the file extension for file to be saved. + // And create your own rules of file type policy. + LPWSTR extension; CHECK_FAILURE(args->get_FileExtension(&extension)); - // Create your own rules of file type policy. if (lstrcmpW(extension, L"eml") == 0) - // Set the `SuppressDefaultPolicy` property to skip the default - // file type policy checking and a possible security alert dialog. - // - // This will consent to save the file. + // Set the `SuppressDefaultPolicy` property to skip the + // default file type policy checking and a possible security + // alert dialog for "eml" file. This will consent to + // save the file. CHECK_FAILURE(args->put_SuppressDefaultPolicy(TRUE)); if (lstrcmpW(extension, L"exe") == 0) - // Set the `Cancel` property to cancel the saving directly. - // - // This will abort to save the file. + // Set the `Cancel` property to cancel the saving for "exe" + // file directly. Save action will be aborted without any + // alert. CHECK_FAILURE(args->put_Cancel(TRUE)); wil::com_ptr deferral; CHECK_FAILURE(args->GetDeferral(&deferral)); @@ -66,8 +66,43 @@ bool ScenarioFileTypePolicyStaging::AddCustomFileTypePolicies() ``` ## .Net/ WinRT -### +This example shows suppressing file type policy, security dialog, and +allow to save the file directly. It also blocks saving the exe file. +The sample code will register the event with custom rules. ```c# +void AddCustomFileTypePoliciesExecuted(object target, ExecutedRoutedEventArgs e) +{ + // Register a handler for the `FileTypePolicyChecking` event. + webView.CoreWebView2.FileTypePolicyChecking += (sender, args) => + { + // Developer can obtain a deferral for the event so that the CoreWebView2 + // doesn't examine the properties we set on the event args until + // after the deferral completes asynchronously. + CoreWebView2Deferral deferral = args.GetDeferral(); + + // We avoid potential reentrancy from running a message loop in the event + // handler. Complete the deferral asynchronously. + System.Threading.SynchronizationContext.Current.Post((_) => + { + using (deferral) + { + // Get the file extension for file to be saved. + // And create your own rules of file type policy. + if (args.FileExtension == "eml") + // Set the `SuppressDefaultPolicy` property to skip the + // default file type policy checking and a possible security + // alert dialog for "eml" file. This will consent to + // save the file. + args.SuppressDefaultPolicy = true; + if (args.FileExtension == "exe") + // Set the `Cancel` property to cancel the saving for "exe" + // file directly. Save action will be aborted without any + // alert. + args.Cancel = true; + } + }, null); + }; +} ``` # API Details @@ -160,4 +195,31 @@ interface ICoreWebView2StagingFileTypePolicyCheckingEventHandler : IUnknown { ## .Net/ WinRT ```c# (but really MIDL3) +namespace Microsoft.Web.WebView2.Core +{ + + runtimeclass CoreWebView2FileTypePolicyCheckingEventArgs; + runtimeclass CoreWebView2; + + runtimeclass CoreWebView2FileTypePolicyCheckingEventArgs + { + Boolean Cancel { get; set; }; + String FileExtension { get; }; + String FilePath { get; }; + Boolean SuppressDefaultPolicy { get; set; }; + String Uri { get; }; + Windows.Foundation.Deferral GetDeferral(); + }; + + runtimeclass CoreWebView2 + { + // ... + + [interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2_25")] + { + event Windows.Foundation.TypedEventHandler + FileTypePolicyChecking; + } + }; +} ``` From daf99fd9b789154a9cb8f64e02d5142503151d64 Mon Sep 17 00:00:00 2001 From: Eain C <41822980+Master-Ukulele@users.noreply.github.com> Date: Tue, 23 Apr 2024 15:37:43 -0700 Subject: [PATCH 4/9] Apply suggestions on description and coding style --- specs/FileTypePolicy.md | 73 ++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/specs/FileTypePolicy.md b/specs/FileTypePolicy.md index 4691f77c0..06f9ae090 100644 --- a/specs/FileTypePolicy.md +++ b/specs/FileTypePolicy.md @@ -14,7 +14,7 @@ We'd appreciate your feedback. # Description We proposed the `CoreWebView2.FileTypePolicyChecking` event. You can register -this event to get the file path, file extension and domain uri information, +this event to get the file path, file extension and URI information, when end users try to save a file from your App. Then you can apply your own rules to allow save the file with, or without a default warning dialog; to cancel the saving; and even to create your own UI to manage runtime @@ -42,21 +42,20 @@ bool ScenarioFileTypePolicyStaging::AddCustomFileTypePolicies() LPWSTR extension; CHECK_FAILURE(args->get_FileExtension(&extension)); if (lstrcmpW(extension, L"eml") == 0) + { // Set the `SuppressDefaultPolicy` property to skip the // default file type policy checking and a possible security // alert dialog for "eml" file. This will consent to // save the file. CHECK_FAILURE(args->put_SuppressDefaultPolicy(TRUE)); + } if (lstrcmpW(extension, L"exe") == 0) + { // Set the `Cancel` property to cancel the saving for "exe" // file directly. Save action will be aborted without any // alert. CHECK_FAILURE(args->put_Cancel(TRUE)); - wil::com_ptr deferral; - CHECK_FAILURE(args->GetDeferral(&deferral)); - - m_appWindow->RunAsync([deferral]() { CHECK_FAILURE(deferral->Complete()); }); - + } return S_OK; }) .Get(), @@ -75,32 +74,23 @@ void AddCustomFileTypePoliciesExecuted(object target, ExecutedRoutedEventArgs e) // Register a handler for the `FileTypePolicyChecking` event. webView.CoreWebView2.FileTypePolicyChecking += (sender, args) => { - // Developer can obtain a deferral for the event so that the CoreWebView2 - // doesn't examine the properties we set on the event args until - // after the deferral completes asynchronously. - CoreWebView2Deferral deferral = args.GetDeferral(); - - // We avoid potential reentrancy from running a message loop in the event - // handler. Complete the deferral asynchronously. - System.Threading.SynchronizationContext.Current.Post((_) => + // Get the file extension for file to be saved. + // And create your own rules of file type policy. + if (args.FileExtension == "eml") { - using (deferral) - { - // Get the file extension for file to be saved. - // And create your own rules of file type policy. - if (args.FileExtension == "eml") - // Set the `SuppressDefaultPolicy` property to skip the - // default file type policy checking and a possible security - // alert dialog for "eml" file. This will consent to - // save the file. - args.SuppressDefaultPolicy = true; - if (args.FileExtension == "exe") - // Set the `Cancel` property to cancel the saving for "exe" - // file directly. Save action will be aborted without any - // alert. - args.Cancel = true; - } - }, null); + // Set the `SuppressDefaultPolicy` property to skip the + // default file type policy checking and a possible security + // alert dialog for "eml" file. This will consent to + // save the file. + args.SuppressDefaultPolicy = true; + } + if (args.FileExtension == "exe") + { + // Set the `Cancel` property to cancel the saving for "exe" + // file directly. Save action will be aborted without any + // alert. + args.Cancel = true; + } }; } ``` @@ -110,7 +100,9 @@ void AddCustomFileTypePoliciesExecuted(object target, ExecutedRoutedEventArgs e) ```c++ interface ICoreWebView2 : IUnknown { /// Adds an event handler for the `FileTypePolicyChecking` event. - /// This event will be raised during system FileTypePolicy + /// If the default save file picker is used to save a file, for + /// example, client using the File System API `showSaveFilePicker`; + /// this event will be raised during system FileTypePolicy /// checking the dangerous file extension list. /// /// Developers can specify their own decision on if allow this file @@ -121,14 +113,14 @@ interface ICoreWebView2 : IUnknown { /// /// | Cancel | SuppressDefaultPolicy | Result /// | ------ | ------ | --------------------- - /// | False | False | Process to default policy check. It might show + /// | False | False | Perform the default policy check. It may show the /// | | | security warning UI if the file extension is /// | | | dangerous. /// | ------ | ------ | --------------------- /// | False | True | Skip the default policy check and the possible /// | | | security warning. Start saving or downloading. /// | ------ | ------ | --------------------- - /// | True | T or F | Skip the default policy check and the possible + /// | True | Any | Skip the default policy check and the possible /// | | | security warning. Abort save or download. HRESULT add_FileTypePolicyChecking( [in] ICoreWebView2StagingFileTypePolicyCheckingEventHandler* eventHandler, @@ -153,10 +145,12 @@ interface ICoreWebView2StagingFileTypePolicyCheckingEventArgs : IUnknown { /// Get the extension of file to be saved. /// - /// File extension can be empty. + /// File extension can be empty, if the file name has no extension + /// at all. /// - /// Only final extension will be provided. For example, "*.tar.gz" - /// is a double extension, where the "gz" will be its final extension. + /// Only final extension without "." will be provided. For example, + /// "*.tar.gz" is a double extension, where the "gz" will be its + /// final extension. /// /// File extension usage in the API is case sensitive. [propget] HRESULT FileExtension([out, retval] LPWSTR* value); @@ -174,11 +168,14 @@ interface ICoreWebView2StagingFileTypePolicyCheckingEventArgs : IUnknown { /// The default value is `FALSE`. [propput] HRESULT SuppressDefaultPolicy([in] BOOL value); - /// Get the uri of file source. + /// The URI source of this file save operation. [propget] HRESULT Uri([out, retval] LPWSTR* value); /// Returns an `ICoreWebView2Deferral` object. Use this operation to complete /// the FileTypePolicyCheckingEvent. + /// + /// The default policy checking and any default UI will be blocked temporarily, + /// saving file to local won't start, until the deferral is completed. HRESULT GetDeferral( [out, retval] ICoreWebView2Deferral** value ); From 5f398221f3231cb9df0e230e606f6bc2daef62bd Mon Sep 17 00:00:00 2001 From: Eain C <41822980+Master-Ukulele@users.noreply.github.com> Date: Fri, 26 Apr 2024 10:51:09 -0700 Subject: [PATCH 5/9] Update names of an event and a property --- specs/FileTypePolicy.md | 52 ++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/specs/FileTypePolicy.md b/specs/FileTypePolicy.md index 06f9ae090..55308ecb5 100644 --- a/specs/FileTypePolicy.md +++ b/specs/FileTypePolicy.md @@ -13,8 +13,8 @@ We'd appreciate your feedback. # Description -We proposed the `CoreWebView2.FileTypePolicyChecking` event. You can register -this event to get the file path, file extension and URI information, +We proposed the `CoreWebView2.SaveFileSecurityCheckStarting` event. You can register +this event to get the file path, file extension and URI source information, when end users try to save a file from your App. Then you can apply your own rules to allow save the file with, or without a default warning dialog; to cancel the saving; and even to create your own UI to manage runtime @@ -30,12 +30,12 @@ bool ScenarioFileTypePolicyStaging::AddCustomFileTypePolicies() { if (!m_webView2Staging25) return false; - // Register a handler for the `FileTypePolicyChecking` event. - m_webView2Staging25->add_FileTypePolicyChecking( - Callback( + // Register a handler for the `SaveFileSecurityCheckStarting` event. + m_webView2Staging25->add_SaveFileSecurityCheckStarting( + Callback( [this]( ICoreWebView2* sender, - ICoreWebView2StagingFileTypePolicyCheckingEventArgs* args) -> HRESULT + ICoreWebView2StagingSaveFileSecurityCheckStartingEventArgs* args) -> HRESULT { // Get the file extension for file to be saved. // And create your own rules of file type policy. @@ -59,7 +59,7 @@ bool ScenarioFileTypePolicyStaging::AddCustomFileTypePolicies() return S_OK; }) .Get(), - &m_fileTypePolicyCheckingToken); + &m_saveFileSecurityCheckStartingToken); return true; } ``` @@ -71,8 +71,8 @@ The sample code will register the event with custom rules. ```c# void AddCustomFileTypePoliciesExecuted(object target, ExecutedRoutedEventArgs e) { - // Register a handler for the `FileTypePolicyChecking` event. - webView.CoreWebView2.FileTypePolicyChecking += (sender, args) => + // Register a handler for the `SaveFileSecurityCheckStarting` event. + webView.CoreWebView2.SaveFileSecurityCheckStarting += (sender, args) => { // Get the file extension for file to be saved. // And create your own rules of file type policy. @@ -99,7 +99,7 @@ void AddCustomFileTypePoliciesExecuted(object target, ExecutedRoutedEventArgs e) ## Win32 C++ ```c++ interface ICoreWebView2 : IUnknown { - /// Adds an event handler for the `FileTypePolicyChecking` event. + /// Adds an event handler for the `SaveFileSecurityCheckStarting` event. /// If the default save file picker is used to save a file, for /// example, client using the File System API `showSaveFilePicker`; /// this event will be raised during system FileTypePolicy @@ -107,7 +107,7 @@ interface ICoreWebView2 : IUnknown { /// /// Developers can specify their own decision on if allow this file /// type extension to be saved, or downloaded. Here are two properties - /// in `ICoreWebView2FileTypePolicyCheckingEventArgs` to manage the + /// in `ICoreWebView2SaveFileSecurityCheckStartingEventArgs` to manage the /// decision, `Cancel` and `SuppressDefaultPolicy`. /// Table of Properties' value and result: /// @@ -122,18 +122,18 @@ interface ICoreWebView2 : IUnknown { /// | ------ | ------ | --------------------- /// | True | Any | Skip the default policy check and the possible /// | | | security warning. Abort save or download. - HRESULT add_FileTypePolicyChecking( - [in] ICoreWebView2StagingFileTypePolicyCheckingEventHandler* eventHandler, + HRESULT add_SaveFileSecurityCheckStarting( + [in] ICoreWebView2StagingSaveFileSecurityCheckStartingEventHandler* eventHandler, [out] EventRegistrationToken* token); - /// Removes an event handler previously added with `add_FileTypePolicyChecking`. - HRESULT remove_FileTypePolicyChecking( + /// Removes an event handler previously added with `add_SaveFileSecurityCheckStarting`. + HRESULT remove_SaveFileSecurityCheckStarting( [in] EventRegistrationToken token); } -/// The event args for `FileTypePolicyChecking` event. -interface ICoreWebView2StagingFileTypePolicyCheckingEventArgs : IUnknown { +/// The event args for `SaveFileSecurityCheckStarting` event. +interface ICoreWebView2StagingSaveFileSecurityCheckStartingEventArgs : IUnknown { /// Gets the `Cancel` property. [propget] HRESULT Cancel([out, retval] BOOL* value); @@ -169,10 +169,10 @@ interface ICoreWebView2StagingFileTypePolicyCheckingEventArgs : IUnknown { [propput] HRESULT SuppressDefaultPolicy([in] BOOL value); /// The URI source of this file save operation. - [propget] HRESULT Uri([out, retval] LPWSTR* value); + [propget] HRESULT SourceUri([out, retval] LPWSTR* value); /// Returns an `ICoreWebView2Deferral` object. Use this operation to complete - /// the FileTypePolicyCheckingEvent. + /// the SaveFileSecurityCheckStartingEvent. /// /// The default policy checking and any default UI will be blocked temporarily, /// saving file to local won't start, until the deferral is completed. @@ -181,12 +181,12 @@ interface ICoreWebView2StagingFileTypePolicyCheckingEventArgs : IUnknown { ); } -/// Receives `FileTypePolicyChecking` events. -interface ICoreWebView2StagingFileTypePolicyCheckingEventHandler : IUnknown { +/// Receives `SaveFileSecurityCheckStarting` events. +interface ICoreWebView2StagingSaveFileSecurityCheckStartingEventHandler : IUnknown { /// Provides the event args for the corresponding event. HRESULT Invoke( [in] ICoreWebView2* sender, - [in] ICoreWebView2StagingFileTypePolicyCheckingEventArgs* args); + [in] ICoreWebView2StagingSaveFileSecurityCheckStartingEventArgs* args); } ``` @@ -195,16 +195,16 @@ interface ICoreWebView2StagingFileTypePolicyCheckingEventHandler : IUnknown { namespace Microsoft.Web.WebView2.Core { - runtimeclass CoreWebView2FileTypePolicyCheckingEventArgs; + runtimeclass CoreWebView2SaveFileSecurityCheckStartingEventArgs; runtimeclass CoreWebView2; - runtimeclass CoreWebView2FileTypePolicyCheckingEventArgs + runtimeclass CoreWebView2SaveFileSecurityCheckStartingEventArgs { Boolean Cancel { get; set; }; String FileExtension { get; }; String FilePath { get; }; Boolean SuppressDefaultPolicy { get; set; }; - String Uri { get; }; + String SourceUri { get; }; Windows.Foundation.Deferral GetDeferral(); }; @@ -215,7 +215,7 @@ namespace Microsoft.Web.WebView2.Core [interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2_25")] { event Windows.Foundation.TypedEventHandler - FileTypePolicyChecking; + SaveFileSecurityCheckStarting; } }; } From c05679c8ea1a34da6c8bcfdae905f7697b8666f8 Mon Sep 17 00:00:00 2001 From: Eain C <41822980+Master-Ukulele@users.noreply.github.com> Date: Tue, 14 May 2024 11:13:58 -0700 Subject: [PATCH 6/9] Apply minor wording suggestions --- specs/FileTypePolicy.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/specs/FileTypePolicy.md b/specs/FileTypePolicy.md index 55308ecb5..6ecdbdd90 100644 --- a/specs/FileTypePolicy.md +++ b/specs/FileTypePolicy.md @@ -2,9 +2,10 @@ File Type Policy API === # Background -When saving a file with original SaveFilePicker, a security alert might be -prompted, because the browser applies the [file type policies](https://learn.microsoft.com/en-us/deployedge/microsoft-edge-security-downloads-interruptions#file-types-requiring-a-gesture) -to protect end users. However, in a WebView2 build App, when end users try +When saving a file with the standard SaveFilePicker (window.showSaveFilePicker), +the user might receive a security alert, as the second prompt to confirm the unsafe file type. +It's because the browser applies the [file type policies](https://learn.microsoft.com/en-us/deployedge/microsoft-edge-security-downloads-interruptions#file-types-requiring-a-gesture) +to protect end users. However, in an app that is using WebView2, when end users try to save a file with a certain file extension, they usually can trust the host App, domain and file extension. So, we provide the App developers the File Type Policy API to manage the file type policies dynamically. @@ -13,17 +14,16 @@ We'd appreciate your feedback. # Description -We proposed the `CoreWebView2.SaveFileSecurityCheckStarting` event. You can register -this event to get the file path, file extension and URI source information, -when end users try to save a file from your App. Then you can apply your own -rules to allow save the file with, or without a default warning dialog; +We proposed the `CoreWebView2.SaveFileSecurityCheckStarting` event. As a developer, you can register a handler on +this event to get the file path, file extension and URI source information. Then you can apply your own +rules to allow save the file without a default file type policy security warning UI; to cancel the saving; and even to create your own UI to manage runtime file type policies. # Examples ## Win32 C++ This example shows suppressing file type policy, security dialog, and -allow to save the file directly. It also blocks saving the exe file. +allows saving eml files directly. It also blocks saving exe files. The sample code will register the event with custom rules. ```c++ bool ScenarioFileTypePolicyStaging::AddCustomFileTypePolicies() @@ -66,7 +66,7 @@ bool ScenarioFileTypePolicyStaging::AddCustomFileTypePolicies() ## .Net/ WinRT This example shows suppressing file type policy, security dialog, and -allow to save the file directly. It also blocks saving the exe file. +allows saving eml files directly. It also blocks saving exe files. The sample code will register the event with custom rules. ```c# void AddCustomFileTypePoliciesExecuted(object target, ExecutedRoutedEventArgs e) @@ -137,7 +137,7 @@ interface ICoreWebView2StagingSaveFileSecurityCheckStartingEventArgs : IUnknown /// Gets the `Cancel` property. [propget] HRESULT Cancel([out, retval] BOOL* value); - /// Set if cancel the upcoming save/download. `TRUE` means the action + /// Set whether to cancel the upcoming save/download. `TRUE` means the action /// will be cancelled before validations in default policy. /// /// The default value is `FALSE`. @@ -152,7 +152,8 @@ interface ICoreWebView2StagingSaveFileSecurityCheckStartingEventArgs : IUnknown /// "*.tar.gz" is a double extension, where the "gz" will be its /// final extension. /// - /// File extension usage in the API is case sensitive. + /// The file extension is the extension portion of the FilePath, + /// preserving original case. [propget] HRESULT FileExtension([out, retval] LPWSTR* value); /// Get the full path of file to be saved. This includes the From 2fbb221d8e12f3d74f817424dc8d78a754eb6908 Mon Sep 17 00:00:00 2001 From: Eain C <41822980+Master-Ukulele@users.noreply.github.com> Date: Wed, 15 May 2024 11:20:13 -0700 Subject: [PATCH 7/9] Rewrite win32 example The rewrite will address the following suggestions: - use m_webview2_25 to match the patterns and simplify to remove the null check. - case insensitive comparison - avoid memory leak with wil::unique_cotaskmem_string - include period for file extension - replace .exe to .iso - show the case of validating a trusted uri for .eml - show the case of using deferral and customized UI --- specs/FileTypePolicy.md | 75 +++++++++++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 22 deletions(-) diff --git a/specs/FileTypePolicy.md b/specs/FileTypePolicy.md index 6ecdbdd90..7134e874f 100644 --- a/specs/FileTypePolicy.md +++ b/specs/FileTypePolicy.md @@ -22,45 +22,76 @@ file type policies. # Examples ## Win32 C++ -This example shows suppressing file type policy, security dialog, and -allows saving eml files directly. It also blocks saving exe files. -The sample code will register the event with custom rules. +This example will register the event with two custom rules. +- Suppressing file type policy, security dialog, and +allows saving ".eml" files directly; when the uri is trusted. +- Showing customized warning UI when saving ".iso" files. +It allows to block the saving directly. ```c++ -bool ScenarioFileTypePolicyStaging::AddCustomFileTypePolicies() +void ScenarioFileTypePolicy::AddCustomFileTypePolicies() { - if (!m_webView2Staging25) - return false; + wil::com_ptr m_webview; + EventRegistrationToken m_saveFileSecurityCheckStartingToken = {}; + auto m_webview2_25 = m_webView.try_query(); // Register a handler for the `SaveFileSecurityCheckStarting` event. - m_webView2Staging25->add_SaveFileSecurityCheckStarting( - Callback( + m_webView2_25->add_saveFileSecurityCheckStarting( + Callback( [this]( ICoreWebView2* sender, - ICoreWebView2StagingSaveFileSecurityCheckStartingEventArgs* args) -> HRESULT + ICoreWebView2SaveFileSecurityCheckStartingEventArgs* args) -> HRESULT { // Get the file extension for file to be saved. - // And create your own rules of file type policy. - LPWSTR extension; + wil::unique_cotaskmem_string extension; CHECK_FAILURE(args->get_FileExtension(&extension)); - if (lstrcmpW(extension, L"eml") == 0) + // Get the uri of file to be saved. + wil::unique_cotaskmem_string uri; + CHECK_FAILURE(args->get_SourceUri(&uri)); + // Convert the file extension value to lower case for + // the case-insensitive comparison. + std::wstring extension_lower = extension.get(); + std::transform( + extension_lower.begin(), extension_lower.end(), + extension_lower.begin(), ::towlower); + // Set the `SuppressDefaultPolicy` property to skip the + // default file type policy checking and a possible security + // alert dialog for ".eml" file, when it's from a trusted uri. + // This will consent to save the file. + // + // 'IsTrustedUri' should be your own helper method + // to determine whether a uri is trusted. + if (wcscmp(extension_lower.c_str(), L".eml") == 0 && IsTrustedUri(uri)) { - // Set the `SuppressDefaultPolicy` property to skip the - // default file type policy checking and a possible security - // alert dialog for "eml" file. This will consent to - // save the file. CHECK_FAILURE(args->put_SuppressDefaultPolicy(TRUE)); } - if (lstrcmpW(extension, L"exe") == 0) + // Show customized warning UI for ".iso" file with + // the deferral. + if (wcscmp(extension_lower.c_str(), L".iso") == 0) { - // Set the `Cancel` property to cancel the saving for "exe" - // file directly. Save action will be aborted without any - // alert. - CHECK_FAILURE(args->put_Cancel(TRUE)); + wil::com_ptr deferral; + CHECK_FAILURE(args->GetDeferral(&deferral)); + + // 'm_appWindow' should be your main app window. + m_appWindow->RunAsync( + [args = wil::make_com_ptr(args), deferral]() + { + // Set the `Cancel` property to cancel the saving + // for ".iso" file directly. Save action will be aborted. + // + // You can let end users make decision on their save + // action with your customized warning UI. + // 'IsCancelledFromCustomizedWarningUI' should be + // your async helper method that retrieves result from the UI. + if (IsCancelledFromCustomizedWarningUI()) + { + CHECK_FAILURE(args->put_Cancel(TRUE)); + } + CHECK_FAILURE(deferral->Complete()); + }); } return S_OK; }) .Get(), &m_saveFileSecurityCheckStartingToken); - return true; } ``` From ade0011ab32f4f4a758e83a40c79939725b2546c Mon Sep 17 00:00:00 2001 From: Eain C <41822980+Master-Ukulele@users.noreply.github.com> Date: Wed, 15 May 2024 14:03:19 -0700 Subject: [PATCH 8/9] Update the rewrite to .net example --- specs/FileTypePolicy.md | 50 ++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/specs/FileTypePolicy.md b/specs/FileTypePolicy.md index 7134e874f..37d022f6a 100644 --- a/specs/FileTypePolicy.md +++ b/specs/FileTypePolicy.md @@ -58,7 +58,7 @@ void ScenarioFileTypePolicy::AddCustomFileTypePolicies() // This will consent to save the file. // // 'IsTrustedUri' should be your own helper method - // to determine whether a uri is trusted. + // to determine whether the uri is trusted. if (wcscmp(extension_lower.c_str(), L".eml") == 0 && IsTrustedUri(uri)) { CHECK_FAILURE(args->put_SuppressDefaultPolicy(TRUE)); @@ -80,7 +80,7 @@ void ScenarioFileTypePolicy::AddCustomFileTypePolicies() // You can let end users make decision on their save // action with your customized warning UI. // 'IsCancelledFromCustomizedWarningUI' should be - // your async helper method that retrieves result from the UI. + // your helper method that retrieves result from the UI. if (IsCancelledFromCustomizedWarningUI()) { CHECK_FAILURE(args->put_Cancel(TRUE)); @@ -96,31 +96,49 @@ void ScenarioFileTypePolicy::AddCustomFileTypePolicies() ``` ## .Net/ WinRT -This example shows suppressing file type policy, security dialog, and -allows saving eml files directly. It also blocks saving exe files. -The sample code will register the event with custom rules. +This example will register the event with two custom rules. +- Suppressing file type policy, security dialog, and +allows saving ".eml" files directly; when the uri is trusted. +- Showing customized warning UI when saving ".iso" files. +It allows to block the saving directly. ```c# -void AddCustomFileTypePoliciesExecuted(object target, ExecutedRoutedEventArgs e) +void AddCustomFileTypePolicies() { // Register a handler for the `SaveFileSecurityCheckStarting` event. webView.CoreWebView2.SaveFileSecurityCheckStarting += (sender, args) => { - // Get the file extension for file to be saved. - // And create your own rules of file type policy. - if (args.FileExtension == "eml") + if (string.Equals(args.FileExtension, ".eml", StringComparison.OrdinalIgnoreCase) + && IsTrustedUri(args.SourceUri)) { // Set the `SuppressDefaultPolicy` property to skip the // default file type policy checking and a possible security - // alert dialog for "eml" file. This will consent to - // save the file. + // alert dialog for ".eml" file, when it's from a trusted uri. + // This will consent to save the file. + // + // 'IsTrustedUri' should be your own helper method + // to determine whether the uri is trusted. args.SuppressDefaultPolicy = true; } - if (args.FileExtension == "exe") + if (string.Equals(args.FileExtension, ".iso", StringComparison.OrdinalIgnoreCase)) { - // Set the `Cancel` property to cancel the saving for "exe" - // file directly. Save action will be aborted without any - // alert. - args.Cancel = true; + CoreWebView2Deferral deferral = args.GetDeferral(); + System.Threading.SynchronizationContext.Current.Post((_) => + { + using (deferral) + { + if (IsCancelledFromCustomizedWarningUI()) + { + // Set the `Cancel` property to cancel the saving + // for ".iso" file directly. Save action will be aborted. + // + // You can let end users make decision on their save + // action with your customized warning UI. + // 'IsCancelledFromCustomizedWarningUI' should be + // your helper method that retrieves result from the UI. + args.Cancel = true; + } + } + }, null); } }; } From b19c17bf276196900c4c252bb2081a5c0c453a94 Mon Sep 17 00:00:00 2001 From: Eain C <41822980+Master-Ukulele@users.noreply.github.com> Date: Wed, 15 May 2024 15:07:46 -0700 Subject: [PATCH 9/9] Rename properties, add description --- specs/FileTypePolicy.md | 107 +++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 51 deletions(-) diff --git a/specs/FileTypePolicy.md b/specs/FileTypePolicy.md index 37d022f6a..a2b389f9c 100644 --- a/specs/FileTypePolicy.md +++ b/specs/FileTypePolicy.md @@ -15,7 +15,7 @@ We'd appreciate your feedback. # Description We proposed the `CoreWebView2.SaveFileSecurityCheckStarting` event. As a developer, you can register a handler on -this event to get the file path, file extension and URI source information. Then you can apply your own +this event to get the file path, file extension and document origin URI information. Then you can apply your own rules to allow save the file without a default file type policy security warning UI; to cancel the saving; and even to create your own UI to manage runtime file type policies. @@ -24,7 +24,7 @@ file type policies. ## Win32 C++ This example will register the event with two custom rules. - Suppressing file type policy, security dialog, and -allows saving ".eml" files directly; when the uri is trusted. +allows saving ".eml" files directly; when the URI is trusted. - Showing customized warning UI when saving ".iso" files. It allows to block the saving directly. ```c++ @@ -32,9 +32,9 @@ void ScenarioFileTypePolicy::AddCustomFileTypePolicies() { wil::com_ptr m_webview; EventRegistrationToken m_saveFileSecurityCheckStartingToken = {}; - auto m_webview2_25 = m_webView.try_query(); + auto m_webview2_23 = m_webView.try_query(); // Register a handler for the `SaveFileSecurityCheckStarting` event. - m_webView2_25->add_saveFileSecurityCheckStarting( + m_webView2_23->add_saveFileSecurityCheckStarting( Callback( [this]( ICoreWebView2* sender, @@ -43,9 +43,9 @@ void ScenarioFileTypePolicy::AddCustomFileTypePolicies() // Get the file extension for file to be saved. wil::unique_cotaskmem_string extension; CHECK_FAILURE(args->get_FileExtension(&extension)); - // Get the uri of file to be saved. + // Get the document origin URI of file to be saved. wil::unique_cotaskmem_string uri; - CHECK_FAILURE(args->get_SourceUri(&uri)); + CHECK_FAILURE(args->get_DocumentOriginUri(&uri)); // Convert the file extension value to lower case for // the case-insensitive comparison. std::wstring extension_lower = extension.get(); @@ -54,11 +54,11 @@ void ScenarioFileTypePolicy::AddCustomFileTypePolicies() extension_lower.begin(), ::towlower); // Set the `SuppressDefaultPolicy` property to skip the // default file type policy checking and a possible security - // alert dialog for ".eml" file, when it's from a trusted uri. + // alert dialog for ".eml" file, when it's from a trusted URI. // This will consent to save the file. // // 'IsTrustedUri' should be your own helper method - // to determine whether the uri is trusted. + // to determine whether the URI is trusted. if (wcscmp(extension_lower.c_str(), L".eml") == 0 && IsTrustedUri(uri)) { CHECK_FAILURE(args->put_SuppressDefaultPolicy(TRUE)); @@ -74,7 +74,7 @@ void ScenarioFileTypePolicy::AddCustomFileTypePolicies() m_appWindow->RunAsync( [args = wil::make_com_ptr(args), deferral]() { - // Set the `Cancel` property to cancel the saving + // Set the `CancelSave` property to cancel the saving // for ".iso" file directly. Save action will be aborted. // // You can let end users make decision on their save @@ -83,7 +83,7 @@ void ScenarioFileTypePolicy::AddCustomFileTypePolicies() // your helper method that retrieves result from the UI. if (IsCancelledFromCustomizedWarningUI()) { - CHECK_FAILURE(args->put_Cancel(TRUE)); + CHECK_FAILURE(args->put_CancelSave(TRUE)); } CHECK_FAILURE(deferral->Complete()); }); @@ -98,7 +98,7 @@ void ScenarioFileTypePolicy::AddCustomFileTypePolicies() ## .Net/ WinRT This example will register the event with two custom rules. - Suppressing file type policy, security dialog, and -allows saving ".eml" files directly; when the uri is trusted. +allows saving ".eml" files directly; when the URI is trusted. - Showing customized warning UI when saving ".iso" files. It allows to block the saving directly. ```c# @@ -108,15 +108,15 @@ void AddCustomFileTypePolicies() webView.CoreWebView2.SaveFileSecurityCheckStarting += (sender, args) => { if (string.Equals(args.FileExtension, ".eml", StringComparison.OrdinalIgnoreCase) - && IsTrustedUri(args.SourceUri)) + && IsTrustedUri(args.DocumentOriginUri)) { // Set the `SuppressDefaultPolicy` property to skip the // default file type policy checking and a possible security - // alert dialog for ".eml" file, when it's from a trusted uri. + // alert dialog for ".eml" file, when it's from a trusted URI. // This will consent to save the file. // // 'IsTrustedUri' should be your own helper method - // to determine whether the uri is trusted. + // to determine whether the URI is trusted. args.SuppressDefaultPolicy = true; } if (string.Equals(args.FileExtension, ".iso", StringComparison.OrdinalIgnoreCase)) @@ -128,14 +128,14 @@ void AddCustomFileTypePolicies() { if (IsCancelledFromCustomizedWarningUI()) { - // Set the `Cancel` property to cancel the saving + // Set the `CancelSave` property to cancel the saving // for ".iso" file directly. Save action will be aborted. // // You can let end users make decision on their save // action with your customized warning UI. // 'IsCancelledFromCustomizedWarningUI' should be // your helper method that retrieves result from the UI. - args.Cancel = true; + args.CancelSave = true; } } }, null); @@ -147,32 +147,34 @@ void AddCustomFileTypePolicies() # API Details ## Win32 C++ ```c++ -interface ICoreWebView2 : IUnknown { +interface ICoreWebView2_23 : ICoreWebView2_22 { /// Adds an event handler for the `SaveFileSecurityCheckStarting` event. /// If the default save file picker is used to save a file, for /// example, client using the File System API `showSaveFilePicker`; /// this event will be raised during system FileTypePolicy /// checking the dangerous file extension list. - /// - /// Developers can specify their own decision on if allow this file - /// type extension to be saved, or downloaded. Here are two properties - /// in `ICoreWebView2SaveFileSecurityCheckStartingEventArgs` to manage the - /// decision, `Cancel` and `SuppressDefaultPolicy`. + /// + /// Developers can specify their own logic for determining whether + /// to allow a particular type of file to be saved from the document origin URI. + /// Developers can also determine the save decision based on other criteria. + /// Here are two properties in `ICoreWebView2SaveFileSecurityCheckStartingEventArgs` + /// to manage the decision, `CancelSave` and `SuppressDefaultPolicy`. + /// /// Table of Properties' value and result: /// - /// | Cancel | SuppressDefaultPolicy | Result - /// | ------ | ------ | --------------------- - /// | False | False | Perform the default policy check. It may show the - /// | | | security warning UI if the file extension is - /// | | | dangerous. - /// | ------ | ------ | --------------------- - /// | False | True | Skip the default policy check and the possible - /// | | | security warning. Start saving or downloading. - /// | ------ | ------ | --------------------- - /// | True | Any | Skip the default policy check and the possible - /// | | | security warning. Abort save or download. + /// | CancelSave | SuppressDefaultPolicy | Result + /// | ---------- | ------ | --------------------- + /// | False | False | Perform the default policy check. It may show the + /// | | | security warning UI if the file extension is + /// | | | dangerous. + /// | ---------- | ------ | --------------------- + /// | False | True | Skip the default policy check and the possible + /// | | | security warning. Start saving or downloading. + /// | ---------- | ------ | --------------------- + /// | True | Any | Skip the default policy check and the possible + /// | | | security warning. Abort save or download. HRESULT add_SaveFileSecurityCheckStarting( - [in] ICoreWebView2StagingSaveFileSecurityCheckStartingEventHandler* eventHandler, + [in] ICoreWebView2SaveFileSecurityCheckStartingEventHandler* eventHandler, [out] EventRegistrationToken* token); /// Removes an event handler previously added with `add_SaveFileSecurityCheckStarting`. @@ -182,31 +184,34 @@ interface ICoreWebView2 : IUnknown { /// The event args for `SaveFileSecurityCheckStarting` event. -interface ICoreWebView2StagingSaveFileSecurityCheckStartingEventArgs : IUnknown { - /// Gets the `Cancel` property. - [propget] HRESULT Cancel([out, retval] BOOL* value); +interface ICoreWebView2SaveFileSecurityCheckStartingEventArgs : IUnknown { + /// Gets the `CancelSave` property. + [propget] HRESULT CancelSave([out, retval] BOOL* value); /// Set whether to cancel the upcoming save/download. `TRUE` means the action /// will be cancelled before validations in default policy. /// /// The default value is `FALSE`. - [propput] HRESULT Cancel([in] BOOL value); + [propput] HRESULT CancelSave([in] BOOL value); /// Get the extension of file to be saved. /// - /// File extension can be empty, if the file name has no extension - /// at all. + /// The file extension is the extension portion of the FilePath, + /// preserving original case. /// - /// Only final extension without "." will be provided. For example, - /// "*.tar.gz" is a double extension, where the "gz" will be its + /// Only final extension with period "." will be provided. For example, + /// "*.tar.gz" is a double extension, where the ".gz" will be its /// final extension. /// - /// The file extension is the extension portion of the FilePath, - /// preserving original case. + /// File extension can be empty, if the file name has no extension + /// at all. [propget] HRESULT FileExtension([out, retval] LPWSTR* value); /// Get the full path of file to be saved. This includes the /// file name and extension. + /// + /// This method doesn't provide path validation, the returned + /// string may longer than MAX_PATH. [propget] HRESULT FilePath([out, retval] LPWSTR* value); /// Gets the `SuppressDefaultPolicy` property. @@ -218,8 +223,8 @@ interface ICoreWebView2StagingSaveFileSecurityCheckStartingEventArgs : IUnknown /// The default value is `FALSE`. [propput] HRESULT SuppressDefaultPolicy([in] BOOL value); - /// The URI source of this file save operation. - [propget] HRESULT SourceUri([out, retval] LPWSTR* value); + /// The document origin URI of this file save operation. + [propget] HRESULT DocumentOriginUri([out, retval] LPWSTR* value); /// Returns an `ICoreWebView2Deferral` object. Use this operation to complete /// the SaveFileSecurityCheckStartingEvent. @@ -232,11 +237,11 @@ interface ICoreWebView2StagingSaveFileSecurityCheckStartingEventArgs : IUnknown } /// Receives `SaveFileSecurityCheckStarting` events. -interface ICoreWebView2StagingSaveFileSecurityCheckStartingEventHandler : IUnknown { +interface ICoreWebView2SaveFileSecurityCheckStartingEventHandler : IUnknown { /// Provides the event args for the corresponding event. HRESULT Invoke( [in] ICoreWebView2* sender, - [in] ICoreWebView2StagingSaveFileSecurityCheckStartingEventArgs* args); + [in] ICoreWebView2SaveFileSecurityCheckStartingEventArgs* args); } ``` @@ -250,11 +255,11 @@ namespace Microsoft.Web.WebView2.Core runtimeclass CoreWebView2SaveFileSecurityCheckStartingEventArgs { - Boolean Cancel { get; set; }; + Boolean CancelSave { get; set; }; String FileExtension { get; }; String FilePath { get; }; Boolean SuppressDefaultPolicy { get; set; }; - String SourceUri { get; }; + String DocumentOriginUri { get; }; Windows.Foundation.Deferral GetDeferral(); }; @@ -262,7 +267,7 @@ namespace Microsoft.Web.WebView2.Core { // ... - [interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2_25")] + [interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2_23")] { event Windows.Foundation.TypedEventHandler SaveFileSecurityCheckStarting;