Skip to content

Commit 5a4f6f4

Browse files
authored
Unblock Internet files on startup (#15)
1 parent d4957bd commit 5a4f6f4

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

NativeConstants.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace CnCNet.LauncherStub;
2+
3+
internal static class NativeConstants
4+
{
5+
/// ERROR_FILE_NOT_FOUND -> 2L
6+
public const int ERROR_FILE_NOT_FOUND = 2;
7+
8+
/// ERROR_ACCESS_DENIED -> 5L
9+
public const int ERROR_ACCESS_DENIED = 5;
10+
}

NativeMethods.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace CnCNet.LauncherStub;
2+
3+
using System.Runtime.InteropServices;
4+
5+
internal static class NativeMethods
6+
{
7+
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
8+
#if NET45_OR_GREATER || NETSTANDARD || NET
9+
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
10+
#endif
11+
[return: MarshalAs(UnmanagedType.Bool)]
12+
public static extern bool DeleteFile(string name);
13+
}

Program.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.IO;
99
using System.Linq;
1010
using System.Reflection;
11+
using System.Runtime.InteropServices;
1112
using Microsoft.Win32;
1213

1314
internal sealed class Program
@@ -87,6 +88,21 @@ private static void RequireDotNetFramework()
8788
[STAThread]
8889
private static void Main(string[] args)
8990
{
91+
try
92+
{
93+
RemoveZoneIdentifer(CurrentDirectory);
94+
}
95+
catch (Exception ex)
96+
{
97+
bool ignoreUnblocking = AdvancedMessageBoxHelper.ShowYesNoMessageBox(
98+
"An error occured when the launcher tried to unblock files. Re-running the launcher with administrator privileges might help.\n\n" + ex.ToString(),
99+
"Client Launcher Warning",
100+
yesText: "Continue", noText: "Exit");
101+
102+
if (!ignoreUnblocking)
103+
Environment.Exit(1);
104+
}
105+
90106
try
91107
{
92108
foreach (string arg in args)
@@ -163,6 +179,37 @@ private static void RunDialogTest()
163179
msgbox.ShowDialog();
164180
}
165181

182+
private static void RemoveZoneIdentifer(string directory)
183+
{
184+
// https://stackoverflow.com/a/6375373
185+
186+
List<string> failedMessages = [];
187+
188+
// Enumerate all files recursively
189+
string[] files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
190+
string[] directories = Directory.GetDirectories(directory, "*", SearchOption.AllDirectories);
191+
192+
// For each file or directory, remove the Zone.Identifier alternate data stream
193+
foreach (string file in files.Concat(directories))
194+
{
195+
string zoneIdentifier = file + ":Zone.Identifier";
196+
bool success = NativeMethods.DeleteFile(zoneIdentifier);
197+
if (!success)
198+
{
199+
int error = Marshal.GetLastWin32Error();
200+
if (error == NativeConstants.ERROR_FILE_NOT_FOUND)
201+
continue;
202+
203+
string errorMessage = new Win32Exception(error).Message;
204+
205+
failedMessages.Add($"{file}: {errorMessage}");
206+
}
207+
}
208+
209+
if (failedMessages.Count > 0)
210+
throw new Exception("Failed to remove Zone.Identifier from the following files:\n" + string.Join("\n", failedMessages));
211+
}
212+
166213
private static void RunXNA()
167214
{
168215
RequireXna();

0 commit comments

Comments
 (0)