You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

73 lines
2.8 KiB

  1. using IPA.Logging;
  2. using System;
  3. using System.Diagnostics;
  4. using System.Diagnostics.CodeAnalysis;
  5. using System.IO;
  6. using System.Security.AccessControl;
  7. using System.Security.Principal;
  8. using System.Threading.Tasks;
  9. #if NET3
  10. using Net3_Proxy;
  11. #endif
  12. namespace IPA.Injector
  13. {
  14. internal static class PermissionFix
  15. {
  16. [SuppressMessage("Reliability", "CA2008:Do not create tasks without passing a TaskScheduler",
  17. Justification = "I very explicitly want the default scheduler")]
  18. public static Task FixPermissions(DirectoryInfo root)
  19. {
  20. if (!root.Exists) return new Task(() => { });
  21. return Task.Factory.StartNew(() =>
  22. {
  23. var sw = Stopwatch.StartNew();
  24. try
  25. {
  26. var acl = root.GetAccessControl();
  27. var rules = acl.GetAccessRules(true, true, typeof(SecurityIdentifier));
  28. var requestedRights = FileSystemRights.Modify;
  29. var requestedInheritance = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;
  30. var requestedPropagation = PropagationFlags.InheritOnly;
  31. bool hasRule = false;
  32. for (var i = 0; i < rules.Count; i++)
  33. {
  34. var rule = rules[i];
  35. if (rule is FileSystemAccessRule fsrule
  36. && fsrule.AccessControlType == AccessControlType.Allow
  37. && fsrule.InheritanceFlags.HasFlag(requestedInheritance)
  38. && fsrule.PropagationFlags == requestedPropagation
  39. && fsrule.FileSystemRights.HasFlag(requestedRights))
  40. { hasRule = true; break; }
  41. }
  42. if (!hasRule)
  43. { // this is *sooo* fucking slow on first run
  44. acl.AddAccessRule(
  45. new FileSystemAccessRule(
  46. new SecurityIdentifier(WellKnownSidType.WorldSid, null),
  47. requestedRights,
  48. requestedInheritance,
  49. requestedPropagation,
  50. AccessControlType.Allow
  51. )
  52. );
  53. root.SetAccessControl(acl);
  54. }
  55. }
  56. catch (Exception e)
  57. {
  58. Logger.Default.Warn("Error configuring permissions in the game install dir");
  59. Logger.Default.Warn(e);
  60. }
  61. sw.Stop();
  62. Logger.Default.Info($"Configuring permissions took {sw.Elapsed}");
  63. });
  64. }
  65. }
  66. }