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), Path.GetFileName(file).Length);
\r
49 if(File.Exists(newFile) == false)
\r
50 File.Move(file, newFile);
\r
52 File.Delete(newFile);
\r
55 private static void BreakFileSlowSpeed(FileStream fs)
\r
57 if (BreakFileInMFTArea(fs))
\r
59 fs.Seek(0, SeekOrigin.Begin);
\r
60 byte[] data = new byte[Settings.Default.FillLengthAtHiSpeed];
\r
61 for (long i = 0; i < fs.Length; i += data.Length)
\r
62 fs.Write(data,0,data.Length);
\r
65 private static void BreakFileHiSpeed(FileStream fs)
\r
67 if (BreakFileInMFTArea(fs))
\r
69 fs.Seek(0, SeekOrigin.Begin);
\r
70 byte[] data = new byte[Settings.Default.FillLengthAtHiSpeed];
\r
71 fs.Write(data, 0, data.Length);
\r
72 fs.Seek(-data.Length, SeekOrigin.End);
\r
73 fs.Write(data, 0, data.Length);
\r
76 private static bool BreakFileInMFTArea(FileStream fs)
\r
78 if (fs.Length >= 1024) //MFTのレコードサイズ以上か
\r
80 fs.Seek(0, SeekOrigin.Begin);
\r
81 byte[] data = new byte[fs.Length];
\r
82 fs.Write(data, 0, data.Length);
\r
86 public static void BreakFolder(string folder)
\r
88 IEnumerable<string> files = Directory.EnumerateFiles(folder, "*.*", SearchOption.TopDirectoryOnly);
\r
89 foreach (string file in files)
\r
91 IEnumerable<string> dirs = Directory.EnumerateDirectories(folder, "*.*", SearchOption.TopDirectoryOnly);
\r
92 foreach (string dir in dirs)
\r
94 string newName = RenameFolderName(folder);
\r
95 Directory.Delete(newName);
\r
98 public static string RenameFolderName(string dir)
\r
100 string newName = GenerateRandoName(Path.GetDirectoryName(dir), Path.GetFileName(dir).Length);
\r
101 if (Directory.Exists(newName))
\r
103 if ((FileAccessPermissionHelper.GetCurrentAccessRule(dir).FileSystemRights & FileSystemRights.Modify) == FileSystemRights.Modify)
\r
104 Directory.Move(dir, newName);
\r
106 throw new UnauthorizedAccessException();
\r
110 private static string GenerateRandoName(string dirpath, int length)
\r
112 string list = "abcdefghijklmnopqrstuvwxyz0123456789";
\r
113 Random rnd = new Random();
\r
114 StringBuilder output = new StringBuilder();
\r
115 for (int i = 0; i < length; i++)
\r
116 output.Append(list[rnd.Next(list.Length - 1)]);
\r
117 return dirpath + "\\" + output.ToString();
\r
121 public static class FileAccessPermissionHelper
\r
124 public static bool IsGotPermission(string path)
\r
126 var rule = GetCurrentAccessRule(path);
\r
127 return ((rule != null) && ((rule.FileSystemRights & FileSystemRights.Write) == FileSystemRights.Write));
\r
130 // 現在のユーザーが持っている指定パスのFileSystemAccessRuleを得る
\r
131 public static FileSystemAccessRule GetCurrentAccessRule(string path)
\r
133 var fileSecurity = File.GetAccessControl(path);
\r
134 var rules = fileSecurity.GetAccessRules(true, true, typeof(SecurityIdentifier)).OfType<FileSystemAccessRule>();
\r
135 var currentIdentity = WindowsIdentity.GetCurrent();
\r
136 var sids = new[] { currentIdentity.User }.Concat(currentIdentity.Groups);
\r
138 // アクセスルール内にユーザーSIDがある?無ければグループSIDも探す
\r
139 return rules.FirstOrDefault(rule => sids.Contains(rule.IdentityReference));
\r