private static void DeleteHelper(string fullPath, string userPath, bool recursive) { int num; Exception exception = null; if (recursive) { Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA(); string fileName = null; if (fullPath.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)) { fileName = fullPath + "*"; } else { fileName = fullPath + Path.DirectorySeparatorChar + "*"; } using (SafeFindHandle handle = Win32Native.FindFirstFile(fileName, data)) { if (handle.IsInvalid) { num = Marshal.GetLastWin32Error(); __Error.WinIOError(num, userPath); } do { if (0 != (data.dwFileAttributes & 0x10)) { if (!data.cFileName.Equals(".") && !data.cFileName.Equals("..")) { if (0 == (data.dwFileAttributes & 0x400)) { string str2 = LongPath.InternalCombine(fullPath, data.cFileName); string str3 = LongPath.InternalCombine(userPath, data.cFileName); try { DeleteHelper(str2, str3, recursive); } catch (Exception exception2) { if (exception == null) { exception = exception2; } } } else { if ((data.dwReserved0 == -1610612733) && !Win32Native.DeleteVolumeMountPoint(LongPath.InternalCombine(fullPath, data.cFileName + Path.DirectorySeparatorChar))) { num = Marshal.GetLastWin32Error(); try { __Error.WinIOError(num, data.cFileName); } catch (Exception exception3) { if (exception == null) { exception = exception3; } } } if (!Win32Native.RemoveDirectory(LongPath.InternalCombine(fullPath, data.cFileName))) { num = Marshal.GetLastWin32Error(); try { __Error.WinIOError(num, data.cFileName); } catch (Exception exception4) { if (exception == null) { exception = exception4; } } } } } } else if (!Win32Native.DeleteFile(LongPath.InternalCombine(fullPath, data.cFileName))) { num = Marshal.GetLastWin32Error(); try { __Error.WinIOError(num, data.cFileName); } catch (Exception exception5) { if (exception == null) { exception = exception5; } } } }while (Win32Native.FindNextFile(handle, data)); num = Marshal.GetLastWin32Error(); } if (exception != null) { throw exception; } if ((num != 0) && (num != 0x12)) { __Error.WinIOError(num, userPath); } } if (!Win32Native.RemoveDirectory(fullPath)) { num = Marshal.GetLastWin32Error(); switch (num) { case 2: num = 3; break; case 5: throw new IOException(Environment.GetResourceString("UnauthorizedAccess_IODenied_Path", new object[] { userPath })); } __Error.WinIOError(num, userPath); } }
private static void DeleteHelper(String fullPath, String userPath, bool recursive, bool throwOnTopLevelDirectoryNotFound) { bool r; int hr; Exception ex = null; // Do not recursively delete through reparse points. Perhaps in a // future version we will add a new flag to control this behavior, // but for now we're much safer if we err on the conservative side. // This applies to symbolic links and mount points. // Note the logic to check whether fullPath is a reparse point is // in Delete(String, String, bool), and will set "recursive" to false. // Note that Win32's DeleteFile and RemoveDirectory will just delete // the reparse point itself. if (recursive) { Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA(); String searchPath = null; if (fullPath.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)) { searchPath = fullPath + "*"; } else { searchPath = fullPath + Path.DirectorySeparatorChar + "*"; } // Open a Find handle using (SafeFindHandle hnd = Win32Native.FindFirstFile(searchPath, data)) { if (hnd.IsInvalid) { hr = Marshal.GetLastWin32Error(); __Error.WinIOError(hr, userPath); } do { bool isDir = (0 != (data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY)); if (isDir) { // Skip ".", "..". if (data.cFileName.Equals(".") || data.cFileName.Equals("..")) { continue; } // Recurse for all directories, unless they are // reparse points. Do not follow mount points nor // symbolic links, but do delete the reparse point // itself. bool shouldRecurse = (0 == (data.dwFileAttributes & (int)FileAttributes.ReparsePoint)); if (shouldRecurse) { String newFullPath = LongPath.InternalCombine(fullPath, data.cFileName); String newUserPath = LongPath.InternalCombine(userPath, data.cFileName); try { DeleteHelper(newFullPath, newUserPath, recursive, false); } catch (Exception e) { if (ex == null) { ex = e; } } } else { // Check to see if this is a mount point, and // unmount it. if (data.dwReserved0 == Win32Native.IO_REPARSE_TAG_MOUNT_POINT) { // Use full path plus a trailing '\' String mountPoint = LongPath.InternalCombine(fullPath, data.cFileName + Path.DirectorySeparatorChar); r = Win32Native.DeleteVolumeMountPoint(mountPoint); if (!r) { hr = Marshal.GetLastWin32Error(); if (hr != Win32Native.ERROR_PATH_NOT_FOUND) { try { __Error.WinIOError(hr, data.cFileName); } catch (Exception e) { if (ex == null) { ex = e; } } } } } // RemoveDirectory on a symbolic link will // remove the link itself. String reparsePoint = LongPath.InternalCombine(fullPath, data.cFileName); r = Win32Native.RemoveDirectory(reparsePoint); if (!r) { hr = Marshal.GetLastWin32Error(); if (hr != Win32Native.ERROR_PATH_NOT_FOUND) { try { __Error.WinIOError(hr, data.cFileName); } catch (Exception e) { if (ex == null) { ex = e; } } } } } } else { String fileName = LongPath.InternalCombine(fullPath, data.cFileName); r = Win32Native.DeleteFile(fileName); if (!r) { hr = Marshal.GetLastWin32Error(); if (hr != Win32Native.ERROR_FILE_NOT_FOUND) { try { __Error.WinIOError(hr, data.cFileName); } catch (Exception e) { if (ex == null) { ex = e; } } } } } } while (Win32Native.FindNextFile(hnd, data)); // Make sure we quit with a sensible error. hr = Marshal.GetLastWin32Error(); } if (ex != null) { throw ex; } if (hr != 0 && hr != Win32Native.ERROR_NO_MORE_FILES) { __Error.WinIOError(hr, userPath); } } r = Win32Native.RemoveDirectory(fullPath); if (!r) { hr = Marshal.GetLastWin32Error(); if (hr == Win32Native.ERROR_FILE_NOT_FOUND) // A dubious error code. { hr = Win32Native.ERROR_PATH_NOT_FOUND; } // This check was originally put in for Win9x (unfortunately without special casing it to be for Win9x only). We can't change the NT codepath now for backcomp reasons. if (hr == Win32Native.ERROR_ACCESS_DENIED) { throw new IOException(Environment.GetResourceString("UnauthorizedAccess_IODenied_Path", userPath)); } // don't throw the DirectoryNotFoundException since this is a subdir and there could be a ---- // between two Directory.Delete callers if (hr == Win32Native.ERROR_PATH_NOT_FOUND && !throwOnTopLevelDirectoryNotFound) { return; } __Error.WinIOError(hr, userPath); } }
private static void DeleteHelper(string fullPath, string userPath, bool recursive, bool throwOnTopLevelDirectoryNotFound) { Exception ex = null; if (recursive) { Win32Native.WIN32_FIND_DATA win32_FIND_DATA = default(Win32Native.WIN32_FIND_DATA); string fileName; if (fullPath.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)) { fileName = fullPath + "*"; } else { fileName = fullPath + Path.DirectorySeparatorChar.ToString() + "*"; } int num; using (SafeFindHandle safeFindHandle = Win32Native.FindFirstFile(fileName, ref win32_FIND_DATA)) { if (safeFindHandle.IsInvalid) { num = Marshal.GetLastWin32Error(); __Error.WinIOError(num, userPath); } for (;;) { bool flag = (win32_FIND_DATA.dwFileAttributes & 16) != 0; if (!flag) { goto IL_180; } if (!win32_FIND_DATA.IsRelativeDirectory) { bool flag2 = (win32_FIND_DATA.dwFileAttributes & 1024) == 0; if (flag2) { string fullPath2 = LongPath.InternalCombine(fullPath, win32_FIND_DATA.cFileName); string userPath2 = LongPath.InternalCombine(userPath, win32_FIND_DATA.cFileName); try { LongPathDirectory.DeleteHelper(fullPath2, userPath2, recursive, false); goto IL_1BD; } catch (Exception ex2) { if (ex == null) { ex = ex2; } goto IL_1BD; } } if (win32_FIND_DATA.dwReserved0 == -1610612733) { string mountPoint = LongPath.InternalCombine(fullPath, win32_FIND_DATA.cFileName + Path.DirectorySeparatorChar.ToString()); if (!Win32Native.DeleteVolumeMountPoint(mountPoint)) { num = Marshal.GetLastWin32Error(); if (num != 3) { try { __Error.WinIOError(num, win32_FIND_DATA.cFileName); } catch (Exception ex3) { if (ex == null) { ex = ex3; } } } } } string path = LongPath.InternalCombine(fullPath, win32_FIND_DATA.cFileName); if (!Win32Native.RemoveDirectory(path)) { num = Marshal.GetLastWin32Error(); if (num != 3) { try { __Error.WinIOError(num, win32_FIND_DATA.cFileName); goto IL_1BD; } catch (Exception ex4) { if (ex == null) { ex = ex4; } goto IL_1BD; } goto IL_180; } } } IL_1BD: if (!Win32Native.FindNextFile(safeFindHandle, ref win32_FIND_DATA)) { break; } continue; IL_180: string path2 = LongPath.InternalCombine(fullPath, win32_FIND_DATA.cFileName); if (Win32Native.DeleteFile(path2)) { goto IL_1BD; } num = Marshal.GetLastWin32Error(); if (num != 2) { try { __Error.WinIOError(num, win32_FIND_DATA.cFileName); } catch (Exception ex5) { if (ex == null) { ex = ex5; } } goto IL_1BD; } goto IL_1BD; } num = Marshal.GetLastWin32Error(); } if (ex != null) { throw ex; } if (num != 0 && num != 18) { __Error.WinIOError(num, userPath); } } if (!Win32Native.RemoveDirectory(fullPath)) { int num = Marshal.GetLastWin32Error(); if (num == 2) { num = 3; } if (num == 5) { throw new IOException(Environment.GetResourceString("UnauthorizedAccess_IODenied_Path", new object[] { userPath })); } if (num == 3 && !throwOnTopLevelDirectoryNotFound) { return; } __Error.WinIOError(num, userPath); } }