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
15 const long ShirnkLength = 1;
\r
17 public static void BreakFileOrFolder(string path)
\r
19 if (Directory.Exists(path))
\r
21 else if (File.Exists(path))
\r
25 public static void BreakFile(string file)
\r
27 FileAttributes attr = File.GetAttributes(file);
\r
29 if ((attr & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
\r
30 File.SetAttributes(file, attr & ~FileAttributes.ReadOnly);
\r
32 if ((attr & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint &&
\r
33 (attr & FileAttributes.SparseFile) != FileAttributes.SparseFile)
\r
34 FillFileContent(file);
\r
36 string newFile = GenerateRandoName(Path.GetDirectoryName(file), Path.GetFileName(file).Length);
\r
37 if(File.Exists(newFile) == false)
\r
38 File.Move(file, newFile);
\r
40 File.Delete(newFile);
\r
43 private static void FillFileContent(string file)
\r
46 FileInfo info = new FileInfo(file);
\r
48 foreach (AlternateDataStreamInfo alt in info.ListAlternateDataStreams())
\r
50 fs = alt.Open(FileMode.Open);
\r
51 BreakFileSlowSpeed(fs);
\r
55 string ext = Path.GetExtension(file);
\r
57 fs = new FileStream(file, FileMode.Open, FileAccess.Write, FileShare.None, 8, FileOptions.WriteThrough);
\r
58 if (Settings.Default.AlwaysSlowSpeed || Settings.Default.SlowSpeedExt.IndexOf(ext) != -1)
\r
59 BreakFileSlowSpeed(fs);
\r
61 BreakFileHiSpeed(fs);
\r
65 private static void BreakFileSlowSpeed(FileStream fs)
\r
67 fs.Seek(0, SeekOrigin.Begin);
\r
68 byte[] data = new byte[Settings.Default.FillLengthAtHiSpeed];
\r
69 for (long i = 0; i < fs.Length; i += data.Length)
\r
70 fs.Write(data,0,data.Length);
\r
72 fs.SetLength(ShirnkLength);
\r
75 private static void BreakFileHiSpeed(FileStream fs)
\r
77 fs.Seek(0, SeekOrigin.Begin);
\r
78 byte[] data = new byte[Settings.Default.FillLengthAtHiSpeed];
\r
79 fs.Write(data, 0, data.Length);
\r
80 fs.Seek(-data.Length, SeekOrigin.End);
\r
81 fs.Write(data, 0, data.Length);
\r
83 fs.SetLength(ShirnkLength);
\r
86 public static void BreakFolder(string folder)
\r
88 DirectoryInfo info = new DirectoryInfo(folder);
\r
89 if ((info.Attributes & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint)
\r
91 IEnumerable<string> files = Directory.EnumerateFiles(folder, "*.*", SearchOption.TopDirectoryOnly);
\r
92 foreach (string file in files)
\r
94 IEnumerable<string> dirs = Directory.EnumerateDirectories(folder, "*.*", SearchOption.TopDirectoryOnly);
\r
95 foreach (string dir in dirs)
\r
98 string newName = RenameFolderName(folder);
\r
99 Directory.Delete(newName);
\r
102 public static string RenameFolderName(string dir)
\r
104 string newName = GenerateRandoName(Path.GetDirectoryName(dir), Path.GetFileName(dir).Length);
\r
105 if (Directory.Exists(newName))
\r
107 if ((FileAccessPermissionHelper.GetCurrentAccessRule(dir).FileSystemRights & FileSystemRights.Modify) == FileSystemRights.Modify)
\r
108 Directory.Move(dir, newName);
\r
110 throw new UnauthorizedAccessException();
\r
114 private static string GenerateRandoName(string dirpath, int length)
\r
116 string list = "abcdefghijklmnopqrstuvwxyz0123456789";
\r
117 Random rnd = new Random();
\r
118 StringBuilder output = new StringBuilder();
\r
119 for (int i = 0; i < length; i++)
\r
120 output.Append(list[rnd.Next(list.Length - 1)]);
\r
121 return dirpath + "\\" + output.ToString();
\r
125 public static class FileAccessPermissionHelper
\r
128 public static bool IsGotPermission(string path)
\r
130 var rule = GetCurrentAccessRule(path);
\r
131 return ((rule != null) && ((rule.FileSystemRights & FileSystemRights.Write) == FileSystemRights.Write));
\r
134 // 現在のユーザーが持っている指定パスのFileSystemAccessRuleを得る
\r
135 public static FileSystemAccessRule GetCurrentAccessRule(string path)
\r
137 var fileSecurity = File.GetAccessControl(path);
\r
138 var rules = fileSecurity.GetAccessRules(true, true, typeof(SecurityIdentifier)).OfType<FileSystemAccessRule>();
\r
139 var currentIdentity = WindowsIdentity.GetCurrent();
\r
140 var sids = new[] { currentIdentity.User }.Concat(currentIdentity.Groups);
\r
142 // アクセスルール内にユーザーSIDがある?無ければグループSIDも探す
\r
143 return rules.FirstOrDefault(rule => sids.Contains(rule.IdentityReference));
\r