Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
FileSystemEnumerator.cs
Go to the documentation of this file.
7
9
11{
13
14 private readonly string _originalRootDirectory;
15
16 private readonly string _rootDirectory;
17
18 private readonly EnumerationOptions _options;
19
20 private readonly object _lock = new object();
21
23
25
26 private IntPtr _buffer;
27
28 private int _bufferLength;
29
31
32 private string _currentPath;
33
34 private bool _lastEntryFound;
35
36 private Queue<(IntPtr Handle, string Path, int RemainingDepth)> _pending;
37
39
40 object? IEnumerator.Current => Current;
41
46
55
57 {
58 return true;
59 }
60
62 {
63 return true;
64 }
65
67
69 {
70 }
71
72 protected virtual bool ContinueOnError(int error)
73 {
74 return false;
75 }
76
77 private unsafe void DirectoryFinished()
78 {
83 {
84 _lastEntryFound = true;
85 }
86 else
87 {
89 }
90 }
91
92 public void Reset()
93 {
94 throw new NotSupportedException();
95 }
96
97 public void Dispose()
98 {
100 GC.SuppressFinalize(this);
101 }
102
103 protected virtual void Dispose(bool disposing)
104 {
105 }
106
111
112 private void Init()
113 {
114 using (default(DisableMediaInsertionPrompt))
115 {
118 {
119 _lastEntryFound = true;
120 }
121 }
124 _bufferLength = ((bufferSize <= 0) ? 4096 : Math.Max(1024, bufferSize));
125 try
126 {
128 }
129 catch
130 {
132 throw;
133 }
134 }
135
136 [MethodImpl(MethodImplOptions.AggressiveInlining)]
137 private unsafe bool GetData()
138 {
141 switch ((uint)num)
142 {
143 case 2147483654u:
145 return false;
146 case 0u:
147 return true;
148 case 3221225487u:
150 return false;
151 default:
152 {
153 int num2 = (int)Interop.NtDll.RtlNtStatusToDosError(num);
155 {
157 return false;
158 }
160 }
161 }
162 }
163
165 {
166 var (num, result) = Interop.NtDll.CreateFile(relativePath, _directoryHandle, Interop.NtDll.CreateDisposition.FILE_OPEN, Interop.NtDll.DesiredAccess.FILE_READ_DATA | Interop.NtDll.DesiredAccess.SYNCHRONIZE, FileShare.ReadWrite | FileShare.Delete, (FileAttributes)0, (Interop.NtDll.CreateOptions)16417u, Interop.ObjectAttributes.OBJ_CASE_INSENSITIVE, null, 0u, null, null);
167 if (num == 0)
168 {
169 return result;
170 }
171 int num2 = (int)Interop.NtDll.RtlNtStatusToDosError((int)num);
173 {
174 return IntPtr.Zero;
175 }
177 }
178
187
188 private IntPtr CreateDirectoryHandle(string path, bool ignoreNotFound = false)
189 {
190 IntPtr intPtr = Interop.Kernel32.CreateFile_IntPtr(path, 1, FileShare.ReadWrite | FileShare.Delete, FileMode.Open, 33554432);
191 if (intPtr == IntPtr.Zero || intPtr == (IntPtr)(-1))
192 {
193 int num = Marshal.GetLastWin32Error();
195 {
196 return IntPtr.Zero;
197 }
198 if (num == 2)
199 {
200 num = 3;
201 }
203 }
204 return intPtr;
205 }
206
208 {
209 if ((!ignoreNotFound || (error != 2 && error != 3 && error != 267)) && (error != 5 || !_options.IgnoreInaccessible))
210 {
211 return ContinueOnError(error);
212 }
213 return true;
214 }
215
216 public unsafe bool MoveNext()
217 {
218 if (_lastEntryFound)
219 {
220 return false;
221 }
223 lock (_lock)
224 {
225 if (_lastEntryFound)
226 {
227 return false;
228 }
229 while (true)
230 {
232 if (_lastEntryFound)
233 {
234 return false;
235 }
237 if ((_entry->FileAttributes & _options.AttributesToSkip) != 0)
238 {
239 continue;
240 }
241 if ((_entry->FileAttributes & FileAttributes.Directory) != 0)
242 {
243 if (_entry->FileName.Length <= 2 && _entry->FileName[0] == '.' && (_entry->FileName.Length != 2 || _entry->FileName[1] == '.'))
244 {
246 {
247 continue;
248 }
249 }
251 {
252 string text = Path.Join(_currentPath.AsSpan(), _entry->FileName);
254 if (intPtr != IntPtr.Zero)
255 {
256 try
257 {
258 if (_pending == null)
259 {
261 }
263 }
264 catch
265 {
267 throw;
268 }
269 }
270 }
271 }
273 {
274 break;
275 }
276 }
278 return true;
279 }
280 }
281
282 private unsafe void FindNextEntry()
283 {
285 if (_entry == null && GetData())
286 {
288 }
289 }
290
291 private bool DequeueNextDirectory()
292 {
293 if (_pending == null || _pending.Count == 0)
294 {
295 return false;
296 }
298 return true;
299 }
300
301 private void InternalDispose(bool disposing)
302 {
303 if (_lock != null)
304 {
305 lock (_lock)
306 {
307 _lastEntryFound = true;
309 if (_pending != null)
310 {
311 while (_pending.Count > 0)
312 {
313 Interop.Kernel32.CloseHandle(_pending.Dequeue().Handle);
314 }
315 _pending = null;
316 }
317 if (_buffer != (IntPtr)0)
318 {
320 }
321 _buffer = default(IntPtr);
322 }
323 }
325 }
326}
static bool CloseHandle(IntPtr handle)
static unsafe IntPtr CreateFile_IntPtr(string lpFileName, int dwDesiredAccess, FileShare dwShareMode, FileMode dwCreationDisposition, int dwFlagsAndAttributes)
Definition Interop.cs:768
static unsafe int NtQueryDirectoryFile(IntPtr FileHandle, IntPtr Event, IntPtr ApcRoutine, IntPtr ApcContext, IO_STATUS_BLOCK *IoStatusBlock, IntPtr FileInformation, uint Length, FILE_INFORMATION_CLASS FileInformationClass, BOOLEAN ReturnSingleEntry, UNICODE_STRING *FileName, BOOLEAN RestartScan)
ObjectAttributes
Definition Interop.cs:1750
static void SuppressFinalize(object obj)
Definition GC.cs:202
Definition GC.cs:8
static EnumerationOptions Default
Queue<(IntPtr Handle, string Path, int RemainingDepth)> _pending
FileSystemEnumerator(string directory, EnumerationOptions? options=null)
bool ContinueOnDirectoryError(int error, bool ignoreNotFound)
virtual void OnDirectoryFinished(ReadOnlySpan< char > directory)
IntPtr CreateDirectoryHandle(string path, bool ignoreNotFound=false)
unsafe Interop.NtDll.FILE_FULL_DIR_INFORMATION * _entry
virtual bool ShouldIncludeEntry(ref FileSystemEntry entry)
unsafe IntPtr CreateRelativeDirectoryHandle(ReadOnlySpan< char > relativePath, string fullPath)
virtual bool ShouldRecurseIntoEntry(ref FileSystemEntry entry)
TResult TransformEntry(ref FileSystemEntry entry)
FileSystemEnumerator(string directory, bool isNormalized, EnumerationOptions options=null)
static string GetFullPath(string path)
Definition Path.cs:881
static string TrimEndingDirectorySeparator(string path)
Definition Path.cs:838
static string Join(ReadOnlySpan< char > path1, ReadOnlySpan< char > path2)
Definition Path.cs:387
static Exception GetExceptionForWin32Error(int errorCode, string path="")
static byte Max(byte val1, byte val2)
Definition Math.cs:738
static void FreeHGlobal(IntPtr hglobal)
Definition Marshal.cs:1680
static IntPtr AllocHGlobal(int cb)
Definition Marshal.cs:625
static int Exchange(ref int location1, int value)
static unsafe FILE_FULL_DIR_INFORMATION * GetNextInfo(FILE_FULL_DIR_INFORMATION *info)
Definition Interop.cs:1533
static unsafe void Initialize(ref FileSystemEntry entry, Interop.NtDll.FILE_FULL_DIR_INFORMATION *info, ReadOnlySpan< char > directory, ReadOnlySpan< char > rootDirectory, ReadOnlySpan< char > originalRootDirectory)
static readonly IntPtr Zero
Definition IntPtr.cs:18