From 830b9d823eead9b598d47740a19e064c3418a776 Mon Sep 17 00:00:00 2001 From: 0x5BFA Date: Fri, 3 May 2024 13:41:04 +0900 Subject: [PATCH 1/8] Removed Vanara.PInvoke.Mpr & Vanara.PInvoke.DwmApi --- .../Data/Models/NetworkConnectionDialog.cs | 91 +++++++++++++------ src/Files.App/Files.App.csproj | 4 +- src/Files.App/NativeMethods.txt | 11 ++- .../Services/NetworkDrivesService.cs | 67 +++++++++----- .../Previews/ShellPreviewViewModel.cs | 66 ++++++++++---- 5 files changed, 167 insertions(+), 72 deletions(-) diff --git a/src/Files.App/Data/Models/NetworkConnectionDialog.cs b/src/Files.App/Data/Models/NetworkConnectionDialog.cs index e9d3c35ee553..82ff5d1b38b5 100644 --- a/src/Files.App/Data/Models/NetworkConnectionDialog.cs +++ b/src/Files.App/Data/Models/NetworkConnectionDialog.cs @@ -5,7 +5,14 @@ using System.Windows.Forms; using Vanara.Extensions; using Vanara.InteropServices; -using static Vanara.PInvoke.Mpr; + + +//using Vanara.Extensions; +//using Vanara.InteropServices; +using Windows.Win32; +using Windows.Win32.Foundation; +using Windows.Win32.NetworkManagement.WNet; +using Windows.Win32.Security.Credentials; namespace Files.App.Data.Models { @@ -17,28 +24,34 @@ namespace Files.App.Data.Models /// public sealed class NetworkConnectionDialog : CommonDialog { - private readonly NETRESOURCE netRes = new(); - private CONNECTDLGSTRUCT dialogOptions; + private NETRESOURCEW netRes = new(); + private CONNECTDLGSTRUCTW dialogOptions; /// Initializes a new instance of the class. public NetworkConnectionDialog() { - dialogOptions.cbStructure = (uint)Marshal.SizeOf(typeof(CONNECTDLGSTRUCT)); - netRes.dwType = NETRESOURCEType.RESOURCETYPE_DISK; + dialogOptions.cbStructure = (uint)Marshal.SizeOf(typeof(CONNECTDLGSTRUCTW)); + netRes.dwType = NET_RESOURCE_TYPE.RESOURCETYPE_DISK; } /// Gets the connected device number. This value is only valid after successfully running the dialog. /// The connected device number. The value is 1 for A:, 2 for B:, 3 for C:, and so on. If the user made a deviceless connection, the value is –1. [Browsable(false)] - public int ConnectedDeviceNumber => dialogOptions.dwDevNum; + public int ConnectedDeviceNumber => (int)dialogOptions.dwDevNum; /// Gets or sets a value indicating whether to hide the check box allowing the user to restore the connection at logon. /// true if hiding restore connection check box; otherwise, false. [DefaultValue(false), Category("Appearance"), Description("Hide the check box allowing the user to restore the connection at logon.")] public bool HideRestoreConnectionCheckBox { - get => dialogOptions.dwFlags.IsFlagSet(CONN_DLG.CONNDLG_HIDE_BOX); - set => dialogOptions.dwFlags = dialogOptions.dwFlags.SetFlags(CONN_DLG.CONNDLG_HIDE_BOX, value); + get => dialogOptions.dwFlags.HasFlag(CONNECTDLGSTRUCT_FLAGS.CONNDLG_HIDE_BOX); + set + { + if (value) + dialogOptions.dwFlags |= CONNECTDLGSTRUCT_FLAGS.CONNDLG_HIDE_BOX; + else + dialogOptions.dwFlags &= ~CONNECTDLGSTRUCT_FLAGS.CONNDLG_HIDE_BOX; + } } /// Gets or sets a value indicating whether restore the connection at logon. @@ -46,11 +59,11 @@ public bool HideRestoreConnectionCheckBox [DefaultValue(false), Category("Behavior"), Description("Restore the connection at logon.")] public bool PersistConnectionAtLogon { - get => dialogOptions.dwFlags.IsFlagSet(CONN_DLG.CONNDLG_PERSIST); + get => dialogOptions.dwFlags.IsFlagSet(CONNECTDLGSTRUCT_FLAGS.CONNDLG_PERSIST); set { - dialogOptions.dwFlags = dialogOptions.dwFlags.SetFlags(CONN_DLG.CONNDLG_PERSIST, value); - dialogOptions.dwFlags = dialogOptions.dwFlags.SetFlags(CONN_DLG.CONNDLG_NOT_PERSIST, !value); + dialogOptions.dwFlags = dialogOptions.dwFlags.SetFlags(CONNECTDLGSTRUCT_FLAGS.CONNDLG_PERSIST, value); + dialogOptions.dwFlags = dialogOptions.dwFlags.SetFlags(CONNECTDLGSTRUCT_FLAGS.CONNDLG_NOT_PERSIST, !value); } } @@ -65,7 +78,20 @@ public bool PersistConnectionAtLogon /// Gets or sets the name of the remote network. /// The name of the remote network. [DefaultValue(null), Category("Behavior"), Description("The value displayed in the path field.")] - public string RemoteNetworkName { get => netRes.lpRemoteName; set => netRes.lpRemoteName = value; } + public string RemoteNetworkName + { + get => netRes.lpRemoteName.ToString(); + set + { + unsafe + { + fixed (char* lpcRemoteName = value) + { + netRes.lpRemoteName = lpcRemoteName; + } + } + } + } /// Gets or sets a value indicating whether to enter the most recently used paths into the combination box. /// true to use MRU path; otherwise, false. @@ -73,23 +99,26 @@ public bool PersistConnectionAtLogon [DefaultValue(false), Category("Behavior"), Description("Enter the most recently used paths into the combination box.")] public bool UseMostRecentPath { - get => dialogOptions.dwFlags.IsFlagSet(CONN_DLG.CONNDLG_USE_MRU); + get => dialogOptions.dwFlags.IsFlagSet(CONNECTDLGSTRUCT_FLAGS.CONNDLG_USE_MRU); set { if (value && !string.IsNullOrEmpty(RemoteNetworkName)) throw new InvalidOperationException($"{nameof(UseMostRecentPath)} cannot be set to true if {nameof(RemoteNetworkName)} has a value."); - dialogOptions.dwFlags = dialogOptions.dwFlags.SetFlags(CONN_DLG.CONNDLG_USE_MRU, value); + dialogOptions.dwFlags = dialogOptions.dwFlags.SetFlags(CONNECTDLGSTRUCT_FLAGS.CONNDLG_USE_MRU, value); } } /// public override void Reset() { - dialogOptions.dwDevNum = -1; - dialogOptions.dwFlags = 0; - dialogOptions.lpConnRes = IntPtr.Zero; - ReadOnlyPath = false; + unsafe + { + dialogOptions.dwDevNum = 0; + dialogOptions.dwFlags = 0; + dialogOptions.lpConnRes = null; + ReadOnlyPath = false; + } } /// @@ -97,20 +126,28 @@ protected override bool RunDialog(IntPtr hwndOwner) { using var lpNetResource = SafeCoTaskMemHandle.CreateFromStructure(netRes); - dialogOptions.hwndOwner = hwndOwner; - dialogOptions.lpConnRes = lpNetResource.DangerousGetHandle(); + unsafe + { + dialogOptions.hwndOwner = new(hwndOwner); + + fixed (NETRESOURCEW* lpConnRes = &netRes) + { + dialogOptions.lpConnRes = lpConnRes; + } - if (ReadOnlyPath && !string.IsNullOrEmpty(netRes.lpRemoteName)) - dialogOptions.dwFlags |= CONN_DLG.CONNDLG_RO_PATH; + if (ReadOnlyPath && !string.IsNullOrEmpty(netRes.lpRemoteName.ToString())) + dialogOptions.dwFlags |= CONNECTDLGSTRUCT_FLAGS.CONNDLG_RO_PATH; - var result = WNetConnectionDialog1(dialogOptions); + var result = PInvoke.WNetConnectionDialog1W(ref dialogOptions); - dialogOptions.lpConnRes = IntPtr.Zero; + dialogOptions.lpConnRes = null; - if (result == unchecked((uint)-1)) - return false; + if (result == unchecked((uint)-1)) + return false; - result.ThrowIfFailed(); + if (result == 0) + throw new Win32Exception("Cannot display dialog"); + } return true; } diff --git a/src/Files.App/Files.App.csproj b/src/Files.App/Files.App.csproj index 118ca8eeb568..082238950a90 100644 --- a/src/Files.App/Files.App.csproj +++ b/src/Files.App/Files.App.csproj @@ -95,10 +95,8 @@ - - - + diff --git a/src/Files.App/NativeMethods.txt b/src/Files.App/NativeMethods.txt index 8b16a3515a08..8690f8fbf893 100644 --- a/src/Files.App/NativeMethods.txt +++ b/src/Files.App/NativeMethods.txt @@ -45,4 +45,13 @@ MoveFileFromApp DeleteFileFromApp RemoveDirectoryFromApp GetKeyState -CreateDirectoryFromApp \ No newline at end of file +CreateDirectoryFromApp +WNetCancelConnection2 +NET_USE_CONNECT_FLAGS +NETRESOURCEW +WNetAddConnection3 +CREDENTIALW +CredWrite +WNetConnectionDialog1 +CONNECTDLGSTRUCTW +DwmSetWindowAttribute diff --git a/src/Files.App/Services/NetworkDrivesService.cs b/src/Files.App/Services/NetworkDrivesService.cs index 00729e557136..635a401c2dac 100644 --- a/src/Files.App/Services/NetworkDrivesService.cs +++ b/src/Files.App/Services/NetworkDrivesService.cs @@ -3,11 +3,10 @@ using System.Runtime.InteropServices; using System.Text; -using Vanara.InteropServices; -using Vanara.PInvoke; -using Vanara.Windows.Shell; -using static Vanara.PInvoke.AdvApi32; -using static Vanara.PInvoke.Mpr; +using Windows.Win32; +using Windows.Win32.Foundation; +using Windows.Win32.NetworkManagement.WNet; +using Windows.Win32.Security.Credentials; namespace Files.App.Services { @@ -54,11 +53,11 @@ public async IAsyncEnumerable GetDrivesAsync() var networkLocations = await Win32Helper.StartSTATask(() => { var locations = new List(); - using (var netHood = new ShellFolder(Shell32.KNOWNFOLDERID.FOLDERID_NetHood)) + using (var netHood = new Vanara.Windows.Shell.ShellFolder(Vanara.PInvoke.Shell32.KNOWNFOLDERID.FOLDERID_NetHood)) { foreach (var item in netHood) { - if (item is ShellLink link) + if (item is Vanara.Windows.Shell.ShellLink link) { locations.Add(ShellFolderExtensions.GetShellLinkItem(link)); } @@ -124,7 +123,11 @@ public async Task UpdateDrivesAsync() /// public bool DisconnectNetworkDrive(ILocatableFolder drive) { - return WNetCancelConnection2(drive.Path.TrimEnd('\\'), CONNECT.CONNECT_UPDATE_PROFILE, true).Succeeded; + return + PInvoke.WNetCancelConnection2W( + drive.Path.TrimEnd('\\'), + (uint)NET_USE_CONNECT_FLAGS.CONNECT_UPDATE_PROFILE, + true) is 0u; } /// @@ -147,16 +150,22 @@ public Task OpenMapNetworkDriveDialogAsync() /// public async Task AuthenticateNetworkShare(string path) { - var netRes = new NETRESOURCE() + var netRes = new NETRESOURCEW() { dwType = NET_RESOURCE_TYPE.RESOURCETYPE_DISK }; + + unsafe { - dwType = NETRESOURCEType.RESOURCETYPE_DISK, - lpRemoteName = path - }; + fixed (char* lpcPath = path) + netRes.lpRemoteName = new PWSTR(lpcPath); + } // If credentials are saved, this will return NO_ERROR - Win32Error connectionError = WNetAddConnection3(HWND.NULL, netRes, null, null, 0); + var connectionError = PInvoke.WNetAddConnection3W(new(nint.Zero), netRes, null, null, 0); + Marshal.GetLastWin32Error(); - if (connectionError == Win32Error.ERROR_LOGON_FAILURE || connectionError == Win32Error.ERROR_ACCESS_DENIED) + // ERROR_LOGON_FAILURE: 0x0000052E + // ERROR_ACCESS_DENIED: 0x00000005 + // NO_ERROR: 0x00000000 + if (connectionError == 0x0000052E || connectionError == 0x00000005) { var dialog = DynamicDialogFactory.GetFor_CredentialEntryDialog(path); await dialog.ShowAsync(); @@ -164,22 +173,32 @@ public async Task AuthenticateNetworkShare(string path) if (credentialsReturned is not null && credentialsReturned[1] != null) { - connectionError = WNetAddConnection3(HWND.NULL, netRes, credentialsReturned[1], credentialsReturned[0], 0); - if (credentialsReturned[2] == "y" && connectionError == Win32Error.NO_ERROR) + connectionError = PInvoke.WNetAddConnection3W(new(nint.Zero), netRes, credentialsReturned[1], credentialsReturned[0], 0); + if (credentialsReturned[2] == "y" && connectionError == 0x00000000) { - var creds = new CREDENTIAL + var creds = new CREDENTIALW() { - TargetName = new StrPtrAuto(path.Substring(2)), - UserName = new StrPtrAuto(credentialsReturned[0]), Type = CRED_TYPE.CRED_TYPE_DOMAIN_PASSWORD, AttributeCount = 0, Persist = CRED_PERSIST.CRED_PERSIST_ENTERPRISE }; - byte[] bPassword = Encoding.Unicode.GetBytes(credentialsReturned[1]); - creds.CredentialBlobSize = (uint)bPassword.Length; - creds.CredentialBlob = Marshal.StringToCoTaskMemUni(credentialsReturned[1]); - CredWrite(creds, 0); + unsafe + { + fixed (char* lpcTargetName = path.Substring(2)) + creds.TargetName = new(lpcTargetName); + + fixed (char* lpcUserName = credentialsReturned[0]) + creds.UserName = new(lpcUserName); + + byte[] bPassword = Encoding.Unicode.GetBytes(credentialsReturned[1]); + creds.CredentialBlobSize = (uint)bPassword.Length; + + fixed (byte* lpCredentialBlob = Encoding.UTF8.GetBytes(credentialsReturned[1])) + creds.CredentialBlob = lpCredentialBlob; + } + + PInvoke.CredWrite(creds, 0); } } else @@ -188,7 +207,7 @@ public async Task AuthenticateNetworkShare(string path) } } - if (connectionError == Win32Error.NO_ERROR) + if (connectionError == 0x00000000) { return true; } diff --git a/src/Files.App/ViewModels/UserControls/Previews/ShellPreviewViewModel.cs b/src/Files.App/ViewModels/UserControls/Previews/ShellPreviewViewModel.cs index 761f1090580d..29e46ea59532 100644 --- a/src/Files.App/ViewModels/UserControls/Previews/ShellPreviewViewModel.cs +++ b/src/Files.App/ViewModels/UserControls/Previews/ShellPreviewViewModel.cs @@ -1,5 +1,4 @@ -using DirectN; -using Files.App.ViewModels.Properties; +using Files.App.ViewModels.Properties; using Microsoft.UI.Content; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Hosting; @@ -7,6 +6,8 @@ using System.Text; using Vanara.PInvoke; using WinRT; +using Windows.Win32; +using Windows.Win32.Graphics.Dwm; using static Vanara.PInvoke.ShlwApi; using static Vanara.PInvoke.User32; @@ -114,23 +115,23 @@ public void LoadPreview(UIElement presenter) private bool ChildWindowToXaml(IntPtr parent, UIElement presenter) { - D3D_DRIVER_TYPE[] driverTypes = + DirectN.D3D_DRIVER_TYPE[] driverTypes = [ - D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_HARDWARE, - D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_WARP, + DirectN.D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_HARDWARE, + DirectN.D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_WARP, ]; - ID3D11Device? d3d11Device = null; - ID3D11DeviceContext? d3d11DeviceContext = null; - D3D_FEATURE_LEVEL featureLevelSupported; + DirectN.ID3D11Device? d3d11Device = null; + DirectN.ID3D11DeviceContext? d3d11DeviceContext = null; + DirectN.D3D_FEATURE_LEVEL featureLevelSupported; foreach (var driveType in driverTypes) { - var hr = D3D11Functions.D3D11CreateDevice( + var hr = DirectN.D3D11Functions.D3D11CreateDevice( null, driveType, IntPtr.Zero, - (uint)D3D11_CREATE_DEVICE_FLAG.D3D11_CREATE_DEVICE_BGRA_SUPPORT, + (uint)DirectN.D3D11_CREATE_DEVICE_FLAG.D3D11_CREATE_DEVICE_BGRA_SUPPORT, null, 0, 7, @@ -144,10 +145,10 @@ private bool ChildWindowToXaml(IntPtr parent, UIElement presenter) if (d3d11Device is null) return false; - IDXGIDevice dxgiDevice = (IDXGIDevice)d3d11Device; - if (Functions.DCompositionCreateDevice(dxgiDevice, typeof(IDCompositionDevice).GUID, out var compDevicePtr).IsError) + DirectN.IDXGIDevice dxgiDevice = (DirectN.IDXGIDevice)d3d11Device; + if (DirectN.Functions.DCompositionCreateDevice(dxgiDevice, typeof(DirectN.IDCompositionDevice).GUID, out var compDevicePtr).IsError) return false; - IDCompositionDevice compDevice = (IDCompositionDevice)Marshal.GetObjectForIUnknown(compDevicePtr); + DirectN.IDCompositionDevice compDevice = (DirectN.IDCompositionDevice)Marshal.GetObjectForIUnknown(compDevicePtr); if (compDevice.CreateVisual(out var childVisual).IsError || compDevice.CreateSurfaceFromHwnd(hwnd.DangerousGetHandle(), out var controlSurface).IsError || @@ -156,7 +157,7 @@ private bool ChildWindowToXaml(IntPtr parent, UIElement presenter) var compositor = ElementCompositionPreview.GetElementVisual(presenter).Compositor; outputLink = ContentExternalOutputLink.Create(compositor); - IDCompositionTarget target = outputLink.As(); + DirectN.IDCompositionTarget target = outputLink.As(); target.SetRoot(childVisual); outputLink.PlacementVisual.Size = new(0, 0); @@ -174,7 +175,18 @@ private bool ChildWindowToXaml(IntPtr parent, UIElement presenter) Marshal.ReleaseComObject(d3d11Device); Marshal.ReleaseComObject(d3d11DeviceContext); - return DwmApi.DwmSetWindowAttribute(hwnd, DwmApi.DWMWINDOWATTRIBUTE.DWMWA_CLOAK, true).Succeeded; + unsafe + { + var dwAttrib = Convert.ToUInt32(true); + + return + PInvoke.DwmSetWindowAttribute( + new((nint)hwnd), + DWMWINDOWATTRIBUTE.DWMWA_CLOAK, + &dwAttrib, + (uint)Marshal.SizeOf(dwAttrib)) + .Succeeded; + } } public void UnloadPreview() @@ -191,7 +203,17 @@ public void PointerEntered(bool onPreview) { if (onPreview) { - DwmApi.DwmSetWindowAttribute(hwnd, DwmApi.DWMWINDOWATTRIBUTE.DWMWA_CLOAK, false); + unsafe + { + var dwAttrib = Convert.ToUInt32(false); + + PInvoke.DwmSetWindowAttribute( + new((nint)hwnd), + DWMWINDOWATTRIBUTE.DWMWA_CLOAK, + &dwAttrib, + (uint)Marshal.SizeOf(dwAttrib)); + } + if (isOfficePreview) Win32Helper.SetWindowLong(hwnd, WindowLongFlags.GWL_EXSTYLE, 0); } @@ -199,7 +221,17 @@ public void PointerEntered(bool onPreview) { Win32Helper.SetWindowLong(hwnd, WindowLongFlags.GWL_EXSTYLE, (nint)(WindowStylesEx.WS_EX_LAYERED | WindowStylesEx.WS_EX_COMPOSITED)); - DwmApi.DwmSetWindowAttribute(hwnd, DwmApi.DWMWINDOWATTRIBUTE.DWMWA_CLOAK, true); + + unsafe + { + var dwAttrib = Convert.ToUInt32(true); + + PInvoke.DwmSetWindowAttribute( + new((nint)hwnd), + DWMWINDOWATTRIBUTE.DWMWA_CLOAK, + &dwAttrib, + (uint)Marshal.SizeOf(dwAttrib)); + } } } } From d7b2e48e363dd2b1ea61f929e1f8801edfcaefd3 Mon Sep 17 00:00:00 2001 From: 0x5BFA Date: Fri, 3 May 2024 13:53:53 +0900 Subject: [PATCH 2/8] Update --- src/Files.App/Data/Models/NetworkConnectionDialog.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Files.App/Data/Models/NetworkConnectionDialog.cs b/src/Files.App/Data/Models/NetworkConnectionDialog.cs index 82ff5d1b38b5..e7352c05cdd7 100644 --- a/src/Files.App/Data/Models/NetworkConnectionDialog.cs +++ b/src/Files.App/Data/Models/NetworkConnectionDialog.cs @@ -5,10 +5,6 @@ using System.Windows.Forms; using Vanara.Extensions; using Vanara.InteropServices; - - -//using Vanara.Extensions; -//using Vanara.InteropServices; using Windows.Win32; using Windows.Win32.Foundation; using Windows.Win32.NetworkManagement.WNet; @@ -86,9 +82,7 @@ public string RemoteNetworkName unsafe { fixed (char* lpcRemoteName = value) - { netRes.lpRemoteName = lpcRemoteName; - } } } } @@ -131,9 +125,7 @@ protected override bool RunDialog(IntPtr hwndOwner) dialogOptions.hwndOwner = new(hwndOwner); fixed (NETRESOURCEW* lpConnRes = &netRes) - { dialogOptions.lpConnRes = lpConnRes; - } if (ReadOnlyPath && !string.IsNullOrEmpty(netRes.lpRemoteName.ToString())) dialogOptions.dwFlags |= CONNECTDLGSTRUCT_FLAGS.CONNDLG_RO_PATH; From 6c13290e079f6d9ad102e4c0ee18b50507ce1525 Mon Sep 17 00:00:00 2001 From: 0x5BFA Date: Sat, 4 May 2024 15:03:30 +0900 Subject: [PATCH 3/8] Improve --- src/Files.App/NativeMethods.txt | 1 + src/Files.App/Services/NetworkDrivesService.cs | 16 ++++++---------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/Files.App/NativeMethods.txt b/src/Files.App/NativeMethods.txt index 8690f8fbf893..8b7e5ac0eb60 100644 --- a/src/Files.App/NativeMethods.txt +++ b/src/Files.App/NativeMethods.txt @@ -55,3 +55,4 @@ CredWrite WNetConnectionDialog1 CONNECTDLGSTRUCTW DwmSetWindowAttribute +WIN32_ERROR diff --git a/src/Files.App/Services/NetworkDrivesService.cs b/src/Files.App/Services/NetworkDrivesService.cs index 635a401c2dac..50151cc74d78 100644 --- a/src/Files.App/Services/NetworkDrivesService.cs +++ b/src/Files.App/Services/NetworkDrivesService.cs @@ -159,13 +159,9 @@ public async Task AuthenticateNetworkShare(string path) } // If credentials are saved, this will return NO_ERROR - var connectionError = PInvoke.WNetAddConnection3W(new(nint.Zero), netRes, null, null, 0); - Marshal.GetLastWin32Error(); + var res = (WIN32_ERROR)PInvoke.WNetAddConnection3W(new(nint.Zero), netRes, null, null, 0); - // ERROR_LOGON_FAILURE: 0x0000052E - // ERROR_ACCESS_DENIED: 0x00000005 - // NO_ERROR: 0x00000000 - if (connectionError == 0x0000052E || connectionError == 0x00000005) + if (res == WIN32_ERROR.ERROR_LOGON_FAILURE || res == WIN32_ERROR.ERROR_ACCESS_DENIED) { var dialog = DynamicDialogFactory.GetFor_CredentialEntryDialog(path); await dialog.ShowAsync(); @@ -173,8 +169,8 @@ public async Task AuthenticateNetworkShare(string path) if (credentialsReturned is not null && credentialsReturned[1] != null) { - connectionError = PInvoke.WNetAddConnection3W(new(nint.Zero), netRes, credentialsReturned[1], credentialsReturned[0], 0); - if (credentialsReturned[2] == "y" && connectionError == 0x00000000) + res = (WIN32_ERROR)PInvoke.WNetAddConnection3W(new(nint.Zero), netRes, credentialsReturned[1], credentialsReturned[0], 0); + if (credentialsReturned[2] == "y" && res == WIN32_ERROR.NO_ERROR) { var creds = new CREDENTIALW() { @@ -207,13 +203,13 @@ public async Task AuthenticateNetworkShare(string path) } } - if (connectionError == 0x00000000) + if (res == WIN32_ERROR.NO_ERROR) { return true; } else { - await DialogDisplayHelper.ShowDialogAsync("NetworkFolderErrorDialogTitle".GetLocalizedResource(), connectionError.ToString().Split(":")[1].Trim()); + await DialogDisplayHelper.ShowDialogAsync("NetworkFolderErrorDialogTitle".GetLocalizedResource(), res.ToString()); return false; } From 1bcf3a955ba6d85c5f10e443d6664965ba231c86 Mon Sep 17 00:00:00 2001 From: 0x5bfa <62196528+0x5bfa@users.noreply.github.com> Date: Thu, 16 May 2024 07:41:28 +0900 Subject: [PATCH 4/8] Req --- .../Data/Models/NetworkConnectionDialog.cs | 42 ++++++++----------- .../Services/NetworkDrivesService.cs | 9 ++-- .../Previews/ShellPreviewViewModel.cs | 8 ++-- 3 files changed, 26 insertions(+), 33 deletions(-) diff --git a/src/Files.App/Data/Models/NetworkConnectionDialog.cs b/src/Files.App/Data/Models/NetworkConnectionDialog.cs index e7352c05cdd7..5d87d6dae786 100644 --- a/src/Files.App/Data/Models/NetworkConnectionDialog.cs +++ b/src/Files.App/Data/Models/NetworkConnectionDialog.cs @@ -104,42 +104,34 @@ public bool UseMostRecentPath } /// - public override void Reset() + public unsafe override void Reset() { - unsafe - { - dialogOptions.dwDevNum = 0; - dialogOptions.dwFlags = 0; - dialogOptions.lpConnRes = null; - ReadOnlyPath = false; - } + dialogOptions.dwDevNum = unchecked((uint)-1); + dialogOptions.dwFlags = 0; + dialogOptions.lpConnRes = null; + ReadOnlyPath = false; } /// - protected override bool RunDialog(IntPtr hwndOwner) + protected unsafe override bool RunDialog(IntPtr hwndOwner) { - using var lpNetResource = SafeCoTaskMemHandle.CreateFromStructure(netRes); + dialogOptions.hwndOwner = new(hwndOwner); - unsafe - { - dialogOptions.hwndOwner = new(hwndOwner); + fixed (NETRESOURCEW* lpConnRes = &netRes) + dialogOptions.lpConnRes = lpConnRes; - fixed (NETRESOURCEW* lpConnRes = &netRes) - dialogOptions.lpConnRes = lpConnRes; + if (ReadOnlyPath && !string.IsNullOrEmpty(netRes.lpRemoteName.ToString())) + dialogOptions.dwFlags |= CONNECTDLGSTRUCT_FLAGS.CONNDLG_RO_PATH; - if (ReadOnlyPath && !string.IsNullOrEmpty(netRes.lpRemoteName.ToString())) - dialogOptions.dwFlags |= CONNECTDLGSTRUCT_FLAGS.CONNDLG_RO_PATH; + var result = PInvoke.WNetConnectionDialog1W(ref dialogOptions); - var result = PInvoke.WNetConnectionDialog1W(ref dialogOptions); + dialogOptions.lpConnRes = null; - dialogOptions.lpConnRes = null; + if ((uint)result == unchecked((uint)-1)) + return false; - if (result == unchecked((uint)-1)) - return false; - - if (result == 0) - throw new Win32Exception("Cannot display dialog"); - } + if (result == 0) + throw new Win32Exception("Cannot display dialog"); return true; } diff --git a/src/Files.App/Services/NetworkDrivesService.cs b/src/Files.App/Services/NetworkDrivesService.cs index fa510fdf28e0..49822d5916af 100644 --- a/src/Files.App/Services/NetworkDrivesService.cs +++ b/src/Files.App/Services/NetworkDrivesService.cs @@ -106,7 +106,8 @@ public bool DisconnectNetworkDrive(ILocatableFolder drive) PInvoke.WNetCancelConnection2W( drive.Path.TrimEnd('\\'), (uint)NET_USE_CONNECT_FLAGS.CONNECT_UPDATE_PROFILE, - true) is 0u; + true) + is WIN32_ERROR.NO_ERROR; } /// @@ -167,10 +168,10 @@ public async Task AuthenticateNetworkShare(string path) creds.UserName = new(lpcUserName); byte[] bPassword = Encoding.Unicode.GetBytes(credentialsReturned[1]); - creds.CredentialBlobSize = (uint)bPassword.Length; - - fixed (byte* lpCredentialBlob = Encoding.UTF8.GetBytes(credentialsReturned[1])) + fixed (byte* lpCredentialBlob = bPassword) creds.CredentialBlob = lpCredentialBlob; + + creds.CredentialBlobSize = (uint)bPassword.Length; } PInvoke.CredWrite(creds, 0); diff --git a/src/Files.App/ViewModels/UserControls/Previews/ShellPreviewViewModel.cs b/src/Files.App/ViewModels/UserControls/Previews/ShellPreviewViewModel.cs index a27173970424..4a932c1de4df 100644 --- a/src/Files.App/ViewModels/UserControls/Previews/ShellPreviewViewModel.cs +++ b/src/Files.App/ViewModels/UserControls/Previews/ShellPreviewViewModel.cs @@ -120,10 +120,10 @@ public void LoadPreview(UIElement presenter) private unsafe bool ChildWindowToXaml(IntPtr parent, UIElement presenter) { - DirectN.D3D_DRIVER_TYPE[] driverTypes = + D3D_DRIVER_TYPE[] driverTypes = [ - DirectN.D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_HARDWARE, - DirectN.D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_WARP, + D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_HARDWARE, + D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_WARP, ]; ID3D11Device? d3d11Device = null; @@ -162,7 +162,7 @@ private unsafe bool ChildWindowToXaml(IntPtr parent, UIElement presenter) var compositor = ElementCompositionPreview.GetElementVisual(presenter).Compositor; outputLink = ContentExternalOutputLink.Create(compositor); - DirectN.IDCompositionTarget target = outputLink.As(); + IDCompositionTarget target = outputLink.As(); target.SetRoot(childVisual); outputLink.PlacementVisual.Size = new(0, 0); From 67f6363039d6eaf8b71762ecd5dfc225dd13803d Mon Sep 17 00:00:00 2001 From: 0x5bfa <62196528+0x5bfa@users.noreply.github.com> Date: Sun, 19 May 2024 15:54:19 +0900 Subject: [PATCH 5/8] Merge correctly --- src/Files.App/Services/CommonDialogService.cs | 75 +++++++++++-------- 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/src/Files.App/Services/CommonDialogService.cs b/src/Files.App/Services/CommonDialogService.cs index 3b7d19d868ea..734b7a17c028 100644 --- a/src/Files.App/Services/CommonDialogService.cs +++ b/src/Files.App/Services/CommonDialogService.cs @@ -179,31 +179,34 @@ public bool Open_NetworkConnectionDialog(nint hWind, bool hideRestoreConnectionC private sealed class NetworkConnectionDialog : CommonDialog { - private readonly Vanara.PInvoke.Mpr.NETRESOURCE netRes = new(); - private Vanara.PInvoke.Mpr.CONNECTDLGSTRUCT dialogOptions; + private NETRESOURCEW netRes = new(); + private CONNECTDLGSTRUCTW dialogOptions; - /// - /// Initializes a new instance of the class. - /// + /// Initializes a new instance of the class. public NetworkConnectionDialog() { - dialogOptions.cbStructure = (uint)Marshal.SizeOf(typeof(Vanara.PInvoke.Mpr.CONNECTDLGSTRUCT)); - netRes.dwType = Vanara.PInvoke.Mpr.NETRESOURCEType.RESOURCETYPE_DISK; + dialogOptions.cbStructure = (uint)Marshal.SizeOf(typeof(CONNECTDLGSTRUCTW)); + netRes.dwType = NET_RESOURCE_TYPE.RESOURCETYPE_DISK; } /// Gets the connected device number. This value is only valid after successfully running the dialog. /// The connected device number. The value is 1 for A:, 2 for B:, 3 for C:, and so on. If the user made a deviceless connection, the value is –1. [Browsable(false)] - public int ConnectedDeviceNumber - => dialogOptions.dwDevNum; + public int ConnectedDeviceNumber => (int)dialogOptions.dwDevNum; /// Gets or sets a value indicating whether to hide the check box allowing the user to restore the connection at logon. /// true if hiding restore connection check box; otherwise, false. [DefaultValue(false), Category("Appearance"), Description("Hide the check box allowing the user to restore the connection at logon.")] public bool HideRestoreConnectionCheckBox { - get => dialogOptions.dwFlags.IsFlagSet(Vanara.PInvoke.Mpr.CONN_DLG.CONNDLG_HIDE_BOX); - set => dialogOptions.dwFlags = dialogOptions.dwFlags.SetFlags(Vanara.PInvoke.Mpr.CONN_DLG.CONNDLG_HIDE_BOX, value); + get => dialogOptions.dwFlags.HasFlag(CONNECTDLGSTRUCT_FLAGS.CONNDLG_HIDE_BOX); + set + { + if (value) + dialogOptions.dwFlags |= CONNECTDLGSTRUCT_FLAGS.CONNDLG_HIDE_BOX; + else + dialogOptions.dwFlags &= ~CONNECTDLGSTRUCT_FLAGS.CONNDLG_HIDE_BOX; + } } /// Gets or sets a value indicating whether restore the connection at logon. @@ -211,11 +214,11 @@ public bool HideRestoreConnectionCheckBox [DefaultValue(false), Category("Behavior"), Description("Restore the connection at logon.")] public bool PersistConnectionAtLogon { - get => dialogOptions.dwFlags.IsFlagSet(Vanara.PInvoke.Mpr.CONN_DLG.CONNDLG_PERSIST); + get => dialogOptions.dwFlags.IsFlagSet(CONNECTDLGSTRUCT_FLAGS.CONNDLG_PERSIST); set { - dialogOptions.dwFlags = dialogOptions.dwFlags.SetFlags(Vanara.PInvoke.Mpr.CONN_DLG.CONNDLG_PERSIST, value); - dialogOptions.dwFlags = dialogOptions.dwFlags.SetFlags(Vanara.PInvoke.Mpr.CONN_DLG.CONNDLG_NOT_PERSIST, !value); + dialogOptions.dwFlags = dialogOptions.dwFlags.SetFlags(CONNECTDLGSTRUCT_FLAGS.CONNDLG_PERSIST, value); + dialogOptions.dwFlags = dialogOptions.dwFlags.SetFlags(CONNECTDLGSTRUCT_FLAGS.CONNDLG_NOT_PERSIST, !value); } } @@ -230,7 +233,18 @@ public bool PersistConnectionAtLogon /// Gets or sets the name of the remote network. /// The name of the remote network. [DefaultValue(null), Category("Behavior"), Description("The value displayed in the path field.")] - public string RemoteNetworkName { get => netRes.lpRemoteName; set => netRes.lpRemoteName = value; } + public string RemoteNetworkName + { + get => netRes.lpRemoteName.ToString(); + set + { + unsafe + { + fixed (char* lpcRemoteName = value) + netRes.lpRemoteName = lpcRemoteName; + } + } + } /// Gets or sets a value indicating whether to enter the most recently used paths into the combination box. /// true to use MRU path; otherwise, false. @@ -238,44 +252,45 @@ public bool PersistConnectionAtLogon [DefaultValue(false), Category("Behavior"), Description("Enter the most recently used paths into the combination box.")] public bool UseMostRecentPath { - get => dialogOptions.dwFlags.IsFlagSet(Vanara.PInvoke.Mpr.CONN_DLG.CONNDLG_USE_MRU); + get => dialogOptions.dwFlags.IsFlagSet(CONNECTDLGSTRUCT_FLAGS.CONNDLG_USE_MRU); set { if (value && !string.IsNullOrEmpty(RemoteNetworkName)) throw new InvalidOperationException($"{nameof(UseMostRecentPath)} cannot be set to true if {nameof(RemoteNetworkName)} has a value."); - dialogOptions.dwFlags = dialogOptions.dwFlags.SetFlags(Vanara.PInvoke.Mpr.CONN_DLG.CONNDLG_USE_MRU, value); + dialogOptions.dwFlags = dialogOptions.dwFlags.SetFlags(CONNECTDLGSTRUCT_FLAGS.CONNDLG_USE_MRU, value); } } /// - public override void Reset() + public unsafe override void Reset() { - dialogOptions.dwDevNum = -1; + dialogOptions.dwDevNum = unchecked((uint)-1); dialogOptions.dwFlags = 0; - dialogOptions.lpConnRes = IntPtr.Zero; + dialogOptions.lpConnRes = null; ReadOnlyPath = false; } /// - protected override bool RunDialog(IntPtr hwndOwner) + protected unsafe override bool RunDialog(IntPtr hwndOwner) { - using var lpNetResource = Vanara.InteropServices.SafeCoTaskMemHandle.CreateFromStructure(netRes); + dialogOptions.hwndOwner = new(hwndOwner); - dialogOptions.hwndOwner = hwndOwner; - dialogOptions.lpConnRes = lpNetResource.DangerousGetHandle(); + fixed (NETRESOURCEW* lpConnRes = &netRes) + dialogOptions.lpConnRes = lpConnRes; - if (ReadOnlyPath && !string.IsNullOrEmpty(netRes.lpRemoteName)) - dialogOptions.dwFlags |= Vanara.PInvoke.Mpr.CONN_DLG.CONNDLG_RO_PATH; + if (ReadOnlyPath && !string.IsNullOrEmpty(netRes.lpRemoteName.ToString())) + dialogOptions.dwFlags |= CONNECTDLGSTRUCT_FLAGS.CONNDLG_RO_PATH; - var result = Vanara.PInvoke.Mpr.WNetConnectionDialog1(dialogOptions); + var result = PInvoke.WNetConnectionDialog1W(ref dialogOptions); - dialogOptions.lpConnRes = IntPtr.Zero; + dialogOptions.lpConnRes = null; - if (result == unchecked((uint)-1)) + if ((uint)result == unchecked((uint)-1)) return false; - result.ThrowIfFailed(); + if (result == 0) + throw new Win32Exception("Cannot display dialog"); return true; } From 5b0796c8459f0e6a1f05ad0adb9d2379061a3ec0 Mon Sep 17 00:00:00 2001 From: 0x5bfa <62196528+0x5bfa@users.noreply.github.com> Date: Sun, 19 May 2024 15:56:00 +0900 Subject: [PATCH 6/8] again 2 --- src/Files.App/Services/CommonDialogService.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Files.App/Services/CommonDialogService.cs b/src/Files.App/Services/CommonDialogService.cs index 734b7a17c028..a60dea64a74e 100644 --- a/src/Files.App/Services/CommonDialogService.cs +++ b/src/Files.App/Services/CommonDialogService.cs @@ -6,7 +6,10 @@ using System.Windows.Forms; using Vanara.Extensions; using Windows.Win32; +using Windows.Win32; using Windows.Win32.Foundation; +using Windows.Win32.NetworkManagement.WNet; +using Windows.Win32.Security.Credentials; using Windows.Win32.System.Com; using Windows.Win32.UI.Shell; using Windows.Win32.UI.Shell.Common; From 8931582cbfe10d31dc5b3bcdb9c7c8d84bbe3543 Mon Sep 17 00:00:00 2001 From: 0x5bfa <62196528+0x5bfa@users.noreply.github.com> Date: Sun, 19 May 2024 16:09:08 +0900 Subject: [PATCH 7/8] Optimize using directives --- src/Files.App/Services/CommonDialogService.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Files.App/Services/CommonDialogService.cs b/src/Files.App/Services/CommonDialogService.cs index a60dea64a74e..c06de3b04cc1 100644 --- a/src/Files.App/Services/CommonDialogService.cs +++ b/src/Files.App/Services/CommonDialogService.cs @@ -6,10 +6,8 @@ using System.Windows.Forms; using Vanara.Extensions; using Windows.Win32; -using Windows.Win32; using Windows.Win32.Foundation; using Windows.Win32.NetworkManagement.WNet; -using Windows.Win32.Security.Credentials; using Windows.Win32.System.Com; using Windows.Win32.UI.Shell; using Windows.Win32.UI.Shell.Common; From ec7eb8a828e2b733cbb7c5c1541d7d305604c4a2 Mon Sep 17 00:00:00 2001 From: 0x5BFA <62196528+0x5bfa@users.noreply.github.com> Date: Sun, 26 May 2024 17:07:30 +0900 Subject: [PATCH 8/8] Update NetworkService.cs --- src/Files.App/Services/NetworkService.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Files.App/Services/NetworkService.cs b/src/Files.App/Services/NetworkService.cs index 3f4ed0a8d38f..e0249c33b7c8 100644 --- a/src/Files.App/Services/NetworkService.cs +++ b/src/Files.App/Services/NetworkService.cs @@ -3,6 +3,8 @@ using System.Runtime.InteropServices; using System.Text; +using Vanara.PInvoke; +using Vanara.Windows.Shell; using Windows.Win32; using Windows.Win32.Foundation; using Windows.Win32.NetworkManagement.WNet;