-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDirectoryValidator.cs
More file actions
139 lines (118 loc) · 4.92 KB
/
DirectoryValidator.cs
File metadata and controls
139 lines (118 loc) · 4.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
public class DirectoryValidator
{
private static readonly HashSet<string> ReservedNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"CON", "PRN", "AUX", "NUL",
"COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9",
"LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9",
".", ".."
};
public static string ValidateDirectory(string path)
{
// 1. 检查路径是否存在且是目录
if (!Directory.Exists(path))
return $"Directory does not exist: {path}";
try
{
string fullPath = Path.GetFullPath(path);
// 2. 检查是否是根目录
string root = Path.GetPathRoot(fullPath);
if (string.Equals(
fullPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar),
root.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar),
StringComparison.OrdinalIgnoreCase))
{
return $"Path is a root directory: {path}";
}
// 3. 检查UNC路径(直接网络共享)
if (IsUncPath(fullPath))
return $"Path is a network share (UNC path): {path}";
// 4. 递归检查目录树
Stack<string> stack = new Stack<string>();
stack.Push(fullPath);
while (stack.Count > 0)
{
string currentDir = stack.Pop();
// 检查当前目录属性
var dirAttrs = File.GetAttributes(currentDir);
if ((dirAttrs & FileAttributes.ReparsePoint) != 0)
return $"Directory is a reparse point: {currentDir}";
// 检查目录名
string dirName = Path.GetFileName(currentDir);
if (ReservedNames.Contains(dirName))
return $"Directory has reserved name: {currentDir}";
try
{
// 处理文件
foreach (string file in Directory.GetFiles(currentDir))
{
string fileName = Path.GetFileName(file);
string baseName = Path.GetFileNameWithoutExtension(fileName);
if (ReservedNames.Contains(fileName)) // 检查完整文件名
return $"File has reserved name: {file}";
if (ReservedNames.Contains(baseName)) // 检查无扩展名部分
return $"File has reserved base name: {file}";
var fileAttrs = File.GetAttributes(file);
if ((fileAttrs & FileAttributes.ReparsePoint) != 0)
return $"File is a reparse point: {file}";
}
// 处理子目录
foreach (string subDir in Directory.GetDirectories(currentDir))
{
var subDirAttrs = File.GetAttributes(subDir);
string subDirName = Path.GetFileName(subDir);
// 立即检查子目录名
if (ReservedNames.Contains(subDirName))
return $"Subdirectory has reserved name: {subDir}";
// 立即检查重解析点
if ((subDirAttrs & FileAttributes.ReparsePoint) != 0)
return $"Subdirectory is a reparse point: {subDir}";
stack.Push(subDir);
}
}
catch (UnauthorizedAccessException)
{
return $"Access denied in directory: {currentDir}";
}
catch (PathTooLongException)
{
return $"Path too long: {currentDir}";
}
catch (DirectoryNotFoundException)
{
return $"Subdirectory not found in: {currentDir}";
}
}
return null; // 所有检查通过
}
catch (Exception ex) when (ex is ArgumentException || ex is NotSupportedException)
{
return $"Invalid path format: {ex.Message}";
}
}
private static bool IsUncPath(string path)
{
if (string.IsNullOrWhiteSpace(path))
return false;
// 检查路径是否以"\\"开头
bool isUnc = path.StartsWith(@"\\", StringComparison.Ordinal);
// 进一步验证UNC格式
if (isUnc)
{
try
{
Uri uri = new Uri(path);
return uri.IsUnc;
}
catch
{
return true; // 如果无法解析为URI但仍以"\\"开头,则视为UNC
}
}
return false;
}
}