3 using System.Collections.Generic;
\r
5 using System.Security.AccessControl;
\r
6 using System.Security.Principal;
\r
8 using Trinet.Core.IO.Ntfs;
\r
9 using CompleteEraser.Properties;
\r
11 namespace CompleteEraser
\r
16 public static void BreakFileOrFolder(string path)
\r
18 if (Directory.Exists(path))
\r
20 else if (File.Exists(path))
\r
24 public static void BreakFile(string file)
\r
26 FileAttributes attr = File.GetAttributes(file);
\r
27 if ((attr & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
\r
28 File.SetAttributes(file, attr & ~FileAttributes.ReadOnly);
\r
30 string ext = Path.GetExtension(file);
\r
33 FileInfo info = new FileInfo(file);
\r
34 foreach (AlternateDataStreamInfo alt in info.ListAlternateDataStreams())
\r
36 fs = alt.Open(FileMode.Open);
\r
37 BreakFileSlowSpeed(fs);
\r
41 fs = new FileStream(file, FileMode.Open);
\r
42 if (Settings.Default.AlwaysSlowSpeed || Settings.Default.SlowSpeedExt.IndexOf(ext) != -1)
\r
43 BreakFileSlowSpeed(fs);
\r
45 BreakFileHiSpeed(fs);
\r
48 string newFile = GenerateRandoName(Path.GetDirectoryName(file), file.Length);
\r
49 File.Move(file, newFile);
\r
51 File.Delete(newFile);
\r
54 private static void BreakFileSlowSpeed(FileStream fs)
\r
56 if (BreakFileInMFTArea(fs))
\r
58 fs.Seek(0, SeekOrigin.Begin);
\r
59 byte[] data = new byte[Settings.Default.FillLengthAtHiSpeed];
\r
60 for (long i = 0; i < fs.Length; i += data.Length)
\r
61 fs.Write(data,0,data.Length);
\r
64 private static void BreakFileHiSpeed(FileStream fs)
\r
66 if (BreakFileInMFTArea(fs))
\r
68 fs.Seek(0, SeekOrigin.Begin);
\r
69 byte[] data = new byte[Settings.Default.FillLengthAtHiSpeed];
\r
70 fs.Write(data, 0, data.Length);
\r
71 fs.Seek(-data.Length, SeekOrigin.End);
\r
72 fs.Write(data, 0, data.Length);
\r
75 private static bool BreakFileInMFTArea(FileStream fs)
\r
77 if (fs.Length >= 1024) //MFTのレコードサイズ以上か
\r
79 fs.Seek(0, SeekOrigin.Begin);
\r
80 byte[] data = new byte[fs.Length];
\r
81 fs.Write(data, 0, data.Length);
\r
85 public static void BreakFolder(string folder)
\r
87 IEnumerable<string> files = Directory.GetFiles(folder, "*.*", SearchOption.AllDirectories);
\r
88 foreach (string file in files)
\r
90 string newName = GenerateRandoName(Path.GetDirectoryName(folder), Path.GetFileName(folder).Length);
\r
91 if ((FileAccessPermissionHelper.GetCurrentAccessRule(folder).FileSystemRights & FileSystemRights.Modify) == FileSystemRights.Modify)
\r
92 Directory.Move(folder, newName);
\r
94 throw new UnauthorizedAccessException();
\r
95 Directory.Delete(newName, true);
\r
98 private static string GenerateRandoName(string dirpath, int length)
\r
100 string list = "abcdefghijklmnopqrstuvwxyz0123456789";
\r
101 Random rnd = new Random();
\r
102 StringBuilder output = new StringBuilder();
\r
103 for (int i = 0; i < length; i++)
\r
104 output.Append(list[rnd.Next(list.Length - 1)]);
\r
105 return dirpath + "\\" + output.ToString();
\r
109 public static class FileAccessPermissionHelper
\r
112 public static bool IsGotPermission(string path)
\r
114 var rule = GetCurrentAccessRule(path);
\r
115 return ((rule != null) && ((rule.FileSystemRights & FileSystemRights.Write) == FileSystemRights.Write));
\r
118 // 現在のユーザーが持っている指定パスのFileSystemAccessRuleを得る
\r
119 public static FileSystemAccessRule GetCurrentAccessRule(string path)
\r
121 var fileSecurity = File.GetAccessControl(path);
\r
122 var rules = fileSecurity.GetAccessRules(true, true, typeof(SecurityIdentifier)).OfType<FileSystemAccessRule>();
\r
123 var currentIdentity = WindowsIdentity.GetCurrent();
\r
124 var sids = new[] { currentIdentity.User }.Concat(currentIdentity.Groups);
\r
126 // アクセスルール内にユーザーSIDがある?無ければグループSIDも探す
\r
127 return rules.FirstOrDefault(rule => sids.Contains(rule.IdentityReference));
\r