Skip to content

Code Quality: Removed Vanara.PInvoke.Mpr & Vanara.PInvoke.DwmApi #15292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 26, 2024
Merged
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
4 changes: 1 addition & 3 deletions src/Files.App/Files.App.csproj
Original file line number Diff line number Diff line change
@@ -93,10 +93,8 @@
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls" Version="7.1.2" />
<PackageReference Include="TagLibSharp" Version="2.3.0" />
<PackageReference Include="Tulpep.ActiveDirectoryObjectPicker" Version="3.0.11" />
<PackageReference Include="Vanara.PInvoke.DwmApi" Version="4.0.1" />
<PackageReference Include="Vanara.Windows.Extensions" Version="4.0.1" />
<PackageReference Include="WinUIEx" Version="2.3.4" />
<PackageReference Include="Vanara.PInvoke.Mpr" Version="4.0.1" />
<PackageReference Include="Vanara.Windows.Extensions" Version="4.0.1" />
<PackageReference Include="Vanara.Windows.Shell" Version="4.0.1" />
<PackageReference Include="Microsoft.Management.Infrastructure" Version="3.0.0" />
<PackageReference Include="Microsoft.Management.Infrastructure.Runtime.Win" Version="3.0.0" />
10 changes: 10 additions & 0 deletions src/Files.App/NativeMethods.txt
Original file line number Diff line number Diff line change
@@ -46,6 +46,16 @@ DeleteFileFromApp
RemoveDirectoryFromApp
GetKeyState
CreateDirectoryFromApp
WNetCancelConnection2
NET_USE_CONNECT_FLAGS
NETRESOURCEW
WNetAddConnection3
CREDENTIALW
CredWrite
WNetConnectionDialog1
CONNECTDLGSTRUCTW
DwmSetWindowAttribute
WIN32_ERROR
CoCreateInstance
FileOpenDialog
IFileOpenDialog
76 changes: 46 additions & 30 deletions src/Files.App/Services/CommonDialogService.cs
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
using Vanara.Extensions;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.NetworkManagement.WNet;
using Windows.Win32.System.Com;
using Windows.Win32.UI.Shell;
using Windows.Win32.UI.Shell.Common;
@@ -179,43 +180,46 @@ 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;

/// <summary>
/// Initializes a new instance of the <see cref="NetworkConnectionDialog"/> class.
/// </summary>
/// <summary>Initializes a new instance of the <see cref="NetworkConnectionDialog"/> class.</summary>
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;
}

/// <summary>Gets the connected device number. This value is only valid after successfully running the dialog.</summary>
/// <value>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.</value>
[Browsable(false)]
public int ConnectedDeviceNumber
=> dialogOptions.dwDevNum;
public int ConnectedDeviceNumber => (int)dialogOptions.dwDevNum;

/// <summary>Gets or sets a value indicating whether to hide the check box allowing the user to restore the connection at logon.</summary>
/// <value><c>true</c> if hiding restore connection check box; otherwise, <c>false</c>.</value>
[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;
}
}

/// <summary>Gets or sets a value indicating whether restore the connection at logon.</summary>
/// <value><c>true</c> to restore connection at logon; otherwise, <c>false</c>.</value>
[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,52 +234,64 @@ public bool PersistConnectionAtLogon
/// <summary>Gets or sets the name of the remote network.</summary>
/// <value>The name of the remote network.</value>
[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;
}
}
}

/// <summary>Gets or sets a value indicating whether to enter the most recently used paths into the combination box.</summary>
/// <value><c>true</c> to use MRU path; otherwise, <c>false</c>.</value>
/// <exception cref="InvalidOperationException">UseMostRecentPath</exception>
[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);
}
}

/// <inheritdoc/>
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;
}

/// <inheritdoc/>
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;
}
60 changes: 39 additions & 21 deletions src/Files.App/Services/NetworkService.cs
Original file line number Diff line number Diff line change
@@ -3,11 +3,12 @@

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
{
@@ -180,7 +181,12 @@ public async Task UpdateShortcutsAsync()
/// <inheritdoc/>
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 WIN32_ERROR.NO_ERROR;
}

/// <inheritdoc/>
@@ -198,39 +204,51 @@ public Task OpenMapNetworkDriveDialogAsync()
/// <inheritdoc/>
public async Task<bool> 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 res = (WIN32_ERROR)PInvoke.WNetAddConnection3W(new(nint.Zero), netRes, null, null, 0);

if (connectionError == Win32Error.ERROR_LOGON_FAILURE || connectionError == Win32Error.ERROR_ACCESS_DENIED)
if (res == WIN32_ERROR.ERROR_LOGON_FAILURE || res == WIN32_ERROR.ERROR_ACCESS_DENIED)
{
var dialog = DynamicDialogFactory.GetFor_CredentialEntryDialog(path);
await dialog.ShowAsync();
var credentialsReturned = dialog.ViewModel.AdditionalData as string[];

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)
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 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]);
fixed (byte* lpCredentialBlob = bPassword)
creds.CredentialBlob = lpCredentialBlob;

creds.CredentialBlobSize = (uint)bPassword.Length;
}

PInvoke.CredWrite(creds, 0);
}
}
else
@@ -239,13 +257,13 @@ public async Task<bool> AuthenticateNetworkShare(string path)
}
}

if (connectionError == Win32Error.NO_ERROR)
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;
}
Original file line number Diff line number Diff line change
@@ -11,6 +11,8 @@
using Windows.Win32.Graphics.Dxgi;
using Windows.Win32.Graphics.DirectComposition;
using WinRT;
using Windows.Win32;
using Windows.Win32.Graphics.Dwm;
using static Vanara.PInvoke.ShlwApi;
using static Vanara.PInvoke.User32;

@@ -178,7 +180,18 @@ private unsafe 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()
@@ -195,15 +208,35 @@ 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);
}
else
{
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));
}
}
}
}