Skip to content

Commit ce6648a

Browse files
authored
Feature: Added banner when Network Discovery is turned off in Windows (#18560)
1 parent 4b9e681 commit ce6648a

14 files changed

Lines changed: 345 additions & 18 deletions

File tree

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
using Files.Shared.Attributes;
5+
using System;
6+
using Windows.Win32.Foundation;
7+
8+
namespace Windows.Win32.UI.Shell
9+
{
10+
public unsafe partial struct IDetectionAndSharing : IComIID
11+
{
12+
[GeneratedVTableFunction(Index = 3)]
13+
public partial HRESULT GetStatus(DTSH_TYPE type, DTSH_STATE* state, DTSH_ACTION* action);
14+
15+
[GuidRVAGen.Guid("1FDA955C-61FF-11DA-978C-0008744FAAB7")]
16+
public static partial ref readonly Guid Guid { get; }
17+
}
18+
19+
public enum DTSH_TYPE
20+
{
21+
DTSH_NETWORK_DISCOVERY = 0,
22+
DTSH_FILE_SHARING = 1,
23+
}
24+
25+
public enum DTSH_STATE
26+
{
27+
DTSH_OFF = 0,
28+
DTSH_ON = 1,
29+
}
30+
31+
public enum DTSH_ACTION
32+
{
33+
DTSH_NONE = 0,
34+
}
35+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
using Files.Shared.Attributes;
5+
using System;
6+
using Windows.Win32.Foundation;
7+
using Windows.Win32.System.Com;
8+
9+
namespace Windows.Win32.UI.Shell
10+
{
11+
public unsafe partial struct IOpenControlPanel : IComIID
12+
{
13+
[GeneratedVTableFunction(Index = 3)]
14+
public partial HRESULT Open(char* name, char* page, void* site);
15+
16+
[GuidRVAGen.Guid("D11AD862-66DE-4DF4-BF6C-1F5621996AF1")]
17+
public static partial ref readonly Guid Guid { get; }
18+
}
19+
}

src/Files.App.CsWin32/ManualGuid.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ public static unsafe partial class CLSID
9595

9696
[GuidRVAGen.Guid("09799AFB-AD67-11D1-ABCD-00C04FC30936")]
9797
public static partial Guid* CLSID_OpenWithMenu { get; }
98+
99+
[GuidRVAGen.Guid("1FDA955B-61FF-11DA-978C-0008744FAAB7")]
100+
public static partial Guid* CLSID_DetectionAndSharing { get; }
101+
102+
[GuidRVAGen.Guid("06622D85-6856-4460-8DE1-A81921B41C4B")]
103+
public static partial Guid* CLSID_OpenControlPanel { get; }
98104
}
99105

100106
public static unsafe partial class BHID

src/Files.App/Data/Contracts/INetworkService.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,18 @@ public interface INetworkService
3939
/// <returns></returns>
4040
Task UpdateShortcutsAsync();
4141

42+
/// <summary>
43+
/// Gets the enabled network discovery and file sharing capabilities.
44+
/// </summary>
45+
/// <returns>The enabled capabilities, or null if the status couldn't be determined.</returns>
46+
Task<NetworkAvailability?> GetNetworkAvailabilityAsync();
47+
48+
/// <summary>
49+
/// Opens Windows advanced sharing settings.
50+
/// </summary>
51+
/// <returns></returns>
52+
Task OpenNetworkSharingSettingsAsync();
53+
4254
/// <summary>
4355
/// Displays the operating system dialog for connecting to a network storage device
4456
/// </summary>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
namespace Files.App.Data.Enums
5+
{
6+
/// <summary>
7+
/// Represents enabled network sharing capabilities.
8+
/// </summary>
9+
[Flags]
10+
public enum NetworkAvailability
11+
{
12+
/// <summary>
13+
/// Neither network discovery nor file sharing is enabled.
14+
/// </summary>
15+
None = 0x0,
16+
17+
/// <summary>
18+
/// Network discovery is enabled.
19+
/// </summary>
20+
Discovery = 0x1,
21+
22+
/// <summary>
23+
/// File sharing is enabled.
24+
/// </summary>
25+
Sharing = 0x2,
26+
27+
/// <summary>
28+
/// Network discovery and file sharing are enabled.
29+
/// </summary>
30+
All = Discovery | Sharing
31+
}
32+
}

src/Files.App/Services/Storage/StorageNetworkService.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,18 @@ public async Task UpdateShortcutsAsync()
185185
Shortcuts.AddIfNotPresent(item);
186186
}
187187

188+
/// <inheritdoc/>
189+
public Task<NetworkAvailability?> GetNetworkAvailabilityAsync()
190+
{
191+
return STATask.Run<NetworkAvailability?>(() => DetectionAndSharingHelper.GetNetworkAvailability(), App.Logger);
192+
}
193+
194+
/// <inheritdoc/>
195+
public Task OpenNetworkSharingSettingsAsync()
196+
{
197+
return STATask.Run(DetectionAndSharingHelper.OpenNetworkSharingSettings, App.Logger);
198+
}
199+
188200
/// <inheritdoc/>
189201
public bool DisconnectNetworkDrive(IFolder drive)
190202
{

src/Files.App/Strings/en-US/Resources.resw

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4328,6 +4328,15 @@
43284328
<data name="OpenSettings" xml:space="preserve">
43294329
<value>Open settings</value>
43304330
</data>
4331+
<data name="NetworkDiscoveryTurnedOffInfoBarMessage" xml:space="preserve">
4332+
<value>Network discovery is turned off. Network computers and devices are not visible.</value>
4333+
</data>
4334+
<data name="FileSharingTurnedOffInfoBarMessage" xml:space="preserve">
4335+
<value>File sharing is turned off. Some network computers and devices might not be visible.</value>
4336+
</data>
4337+
<data name="NetworkDiscoveryAndFileSharingTurnedOffInfoBarMessage" xml:space="preserve">
4338+
<value>Network discovery and file sharing are turned off. Network computers and devices are not visible.</value>
4339+
</data>
43314340
<data name="VisualStudioCode" xml:space="preserve">
43324341
<value>Visual Studio Code</value>
43334342
</data>
@@ -4587,4 +4596,4 @@
45874596
<data name="ConfirmRemoveTagsDialogContent" xml:space="preserve">
45884597
<value>Are you sure you want to remove tags from the selected items?</value>
45894598
</data>
4590-
</root>
4599+
</root>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
using System.Runtime.InteropServices;
5+
using Windows.Win32;
6+
using Windows.Win32.Foundation;
7+
using Windows.Win32.System.Com;
8+
using Windows.Win32.UI.Shell;
9+
10+
namespace Files.App.Utils.Shell
11+
{
12+
internal static class DetectionAndSharingHelper
13+
{
14+
public static unsafe NetworkAvailability GetNetworkAvailability()
15+
{
16+
using ComPtr<IDetectionAndSharing> dtsh = CreateDetectionAndSharing();
17+
var availability = NetworkAvailability.None;
18+
19+
if (IsEnabled(dtsh.Get(), DTSH_TYPE.DTSH_NETWORK_DISCOVERY))
20+
availability |= NetworkAvailability.Discovery;
21+
22+
if (IsEnabled(dtsh.Get(), DTSH_TYPE.DTSH_FILE_SHARING))
23+
availability |= NetworkAvailability.Sharing;
24+
25+
return availability;
26+
}
27+
28+
public static unsafe void OpenNetworkSharingSettings()
29+
{
30+
using ComPtr<IOpenControlPanel> controlPanel = default;
31+
HRESULT hr = controlPanel.CoCreateInstance(CLSID.CLSID_OpenControlPanel, null, CLSCTX.CLSCTX_INPROC_SERVER);
32+
ThrowIfFailed(hr, "Failed to create open control panel object.");
33+
34+
fixed (char* name = "Microsoft.NetworkAndSharingCenter")
35+
fixed (char* page = "Advanced")
36+
{
37+
hr = controlPanel.Get()->Open(name, page, null);
38+
ThrowIfFailed(hr, "Failed to open advanced sharing settings.");
39+
}
40+
}
41+
42+
private static unsafe ComPtr<IDetectionAndSharing> CreateDetectionAndSharing()
43+
{
44+
ComPtr<IDetectionAndSharing> dtsh = default;
45+
HRESULT hr = dtsh.CoCreateInstance(CLSID.CLSID_DetectionAndSharing, null, CLSCTX.CLSCTX_INPROC_SERVER);
46+
ThrowIfFailed(hr, "Failed to create detection and sharing object.");
47+
48+
return dtsh;
49+
}
50+
51+
private static unsafe bool IsEnabled(IDetectionAndSharing* dtsh, DTSH_TYPE type)
52+
{
53+
DTSH_STATE state;
54+
DTSH_ACTION action;
55+
HRESULT hr = dtsh->GetStatus(type, &state, &action);
56+
ThrowIfFailed(hr, $"Failed to get {type} status.");
57+
58+
return state is DTSH_STATE.DTSH_ON;
59+
}
60+
61+
private static void ThrowIfFailed(HRESULT hr, string message)
62+
{
63+
if (hr.Failed)
64+
throw new COMException(message, hr.Value);
65+
}
66+
}
67+
}

src/Files.App/ViewModels/MainPageViewModel.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ public bool ShowSponsorPrompt
161161
public ICommand DismissReviewPromptCommand { get; }
162162
public ICommand SponsorCommand { get; }
163163
public ICommand DismissSponsorPromptCommand { get; }
164+
public ICommand OpenNetworkSharingSettingsCommand { get; }
164165

165166
// Constructor
166167

@@ -171,6 +172,7 @@ public MainPageViewModel()
171172
DismissReviewPromptCommand = new RelayCommand(ExecuteDismissReviewPromptCommand);
172173
SponsorCommand = new RelayCommand(ExecuteSponsorCommand);
173174
DismissSponsorPromptCommand = new RelayCommand(ExecuteDismissSponsorPromptCommand);
175+
OpenNetworkSharingSettingsCommand = new AsyncRelayCommand(ExecuteOpenNetworkSharingSettingsCommand);
174176

175177
AppearanceSettingsService.PropertyChanged += (s, e) =>
176178
{
@@ -370,6 +372,11 @@ private void ExecuteDismissSponsorPromptCommand()
370372
UserSettingsService.ApplicationSettingsService.HasClickedSponsorPrompt = true;
371373
}
372374

375+
private async Task ExecuteOpenNetworkSharingSettingsCommand()
376+
{
377+
await NetworkService.OpenNetworkSharingSettingsAsync();
378+
}
379+
373380
private async void ExecuteNavigateToNumberedTabKeyboardAcceleratorCommand(KeyboardAcceleratorInvokedEventArgs? e)
374381
{
375382
var indexToSelect = e!.KeyboardAccelerator.Key switch

0 commit comments

Comments
 (0)