diff --git a/IPA.Injector/IPA.Injector.csproj b/IPA.Injector/IPA.Injector.csproj index 4ce26d0b..12dfc25d 100644 --- a/IPA.Injector/IPA.Injector.csproj +++ b/IPA.Injector/IPA.Injector.csproj @@ -56,6 +56,7 @@ + diff --git a/IPA.Injector/Injector.cs b/IPA.Injector/Injector.cs index f9a55974..8a8bb50b 100644 --- a/IPA.Injector/Injector.cs +++ b/IPA.Injector/Injector.cs @@ -19,6 +19,7 @@ namespace IPA.Injector public static class Injector { private static Task pluginAsyncLoadTask; + private static Task permissionFixTask; // ReSharper disable once UnusedParameter.Global public static void Main(string[] args) @@ -62,6 +63,7 @@ namespace IPA.Injector LibLoader.SetupAssemblyFilenames(true); pluginAsyncLoadTask = PluginLoader.LoadTask(); + permissionFixTask = PermissionFix.FixPermissions(new DirectoryInfo(Environment.CurrentDirectory)); } catch (Exception e) { @@ -264,6 +266,7 @@ namespace IPA.Injector { // wait for plugins to finish loading pluginAsyncLoadTask.Wait(); + permissionFixTask.Wait(); log.Debug("Plugins loaded"); log.Debug(string.Join(", ", PluginLoader.PluginsMetadata)); PluginComponent.Create(); diff --git a/IPA.Injector/PermissionFix.cs b/IPA.Injector/PermissionFix.cs new file mode 100644 index 00000000..bd8c4723 --- /dev/null +++ b/IPA.Injector/PermissionFix.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security.AccessControl; +using System.Security.Principal; +using System.Text; +using System.Threading.Tasks; + +namespace IPA.Injector +{ + internal static class PermissionFix + { + public static Task FixPermissions(DirectoryInfo root) + { + if (!root.Exists) return Task.CompletedTask; + + return Task.Run(() => + { + try + { + var acl = root.GetAccessControl(); + + var rules = acl.GetAccessRules(true, true, typeof(SecurityIdentifier)); + + var requestedRights = FileSystemRights.Modify; + var requestedInheritance = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit; + var requestedPropagation = PropagationFlags.InheritOnly; + + bool hasRule = false; + for (var i = 0; i < rules.Count; i++) + { + var rule = rules[i]; + + if (rule is FileSystemAccessRule fsrule + && fsrule.AccessControlType == AccessControlType.Allow + && fsrule.InheritanceFlags.HasFlag(requestedInheritance) + && fsrule.PropagationFlags == requestedPropagation + && fsrule.FileSystemRights.HasFlag(requestedRights)) + { hasRule = true; break; } + } + + if (!hasRule) + { // this is *sooo* fucking slow on first run + acl.AddAccessRule( + new FileSystemAccessRule( + new SecurityIdentifier(WellKnownSidType.WorldSid, null), + requestedRights, + requestedInheritance, + requestedPropagation, + AccessControlType.Allow + ) + ); + root.SetAccessControl(acl); + } + } + catch (Exception e) + { + Logging.Logger.log.Warn("Error configuring permissions in the game install dir"); + Logging.Logger.log.Warn(e); + } + }); + } + } +} diff --git a/Refs/Assembly-CSharp.dll b/Refs/Assembly-CSharp.dll index f560a39b..40b6c6cd 100644 Binary files a/Refs/Assembly-CSharp.dll and b/Refs/Assembly-CSharp.dll differ diff --git a/Refs/Unity.TextMeshPro.dll b/Refs/Unity.TextMeshPro.dll index 8a8bce24..8cbb4606 100644 Binary files a/Refs/Unity.TextMeshPro.dll and b/Refs/Unity.TextMeshPro.dll differ