System.IO.Win32FileSystem.RemoveDirectoryHelper C# (CSharp) Méthode

RemoveDirectoryHelper() private méthode

private RemoveDirectoryHelper ( string fullPath, bool recursive, bool throwOnTopLevelDirectoryNotFound ) : void
fullPath string
recursive bool
throwOnTopLevelDirectoryNotFound bool
Résultat void
        private static void RemoveDirectoryHelper(string fullPath, bool recursive, bool throwOnTopLevelDirectoryNotFound)
        {
            bool r;
            int errorCode;
            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)
            {
                Interop.Kernel32.WIN32_FIND_DATA data = new Interop.Kernel32.WIN32_FIND_DATA();

                // Open a Find handle
                using (SafeFindHandle hnd = Interop.Kernel32.FindFirstFile(Directory.EnsureTrailingDirectorySeparator(fullPath) + "*", ref data))
                {
                    if (hnd.IsInvalid)
                        throw Win32Marshal.GetExceptionForLastWin32Error(fullPath);

                    do
                    {
                        bool isDir = (0 != (data.dwFileAttributes & Interop.Kernel32.FileAttributes.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 = Path.Combine(fullPath, data.cFileName);
                                try
                                {
                                    RemoveDirectoryHelper(newFullPath, 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 == Interop.Kernel32.IOReparseOptions.IO_REPARSE_TAG_MOUNT_POINT)
                                {
                                    // Use full path plus a trailing '\'
                                    String mountPoint = Path.Combine(fullPath, data.cFileName + PathHelpers.DirectorySeparatorCharAsString);
                                    if (!Interop.Kernel32.DeleteVolumeMountPoint(mountPoint))
                                    {
                                         errorCode = Marshal.GetLastWin32Error();
                                    
                                        if (errorCode != Interop.Errors.ERROR_SUCCESS && 
                                            errorCode != Interop.Errors.ERROR_PATH_NOT_FOUND)
                                        {
                                            try
                                            {
                                                throw Win32Marshal.GetExceptionForWin32Error(errorCode, data.cFileName);
                                            }
                                            catch (Exception e)
                                            {
                                                if (ex == null)
                                                    ex = e;
                                            }
                                        }
                                    }
                                }

                                // RemoveDirectory on a symbolic link will
                                // remove the link itself.
                                String reparsePoint = Path.Combine(fullPath, data.cFileName);
                                r = Interop.Kernel32.RemoveDirectory(reparsePoint);
                                if (!r)
                                {
                                    errorCode = Marshal.GetLastWin32Error();
                                    if (errorCode != Interop.Errors.ERROR_PATH_NOT_FOUND)
                                    {
                                        try
                                        {
                                            throw Win32Marshal.GetExceptionForWin32Error(errorCode, data.cFileName);
                                        }
                                        catch (Exception e)
                                        {
                                            if (ex == null)
                                                ex = e;
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            String fileName = Path.Combine(fullPath, data.cFileName);
                            r = Interop.Kernel32.DeleteFile(fileName);
                            if (!r)
                            {
                                errorCode = Marshal.GetLastWin32Error();
                                if (errorCode != Interop.Errors.ERROR_FILE_NOT_FOUND)
                                {
                                    try
                                    {
                                        throw Win32Marshal.GetExceptionForWin32Error(errorCode, data.cFileName);
                                    }
                                    catch (Exception e)
                                    {
                                        if (ex == null)
                                            ex = e;
                                    }
                                }
                            }
                        }
                    } while (Interop.Kernel32.FindNextFile(hnd, ref data));
                    // Make sure we quit with a sensible error.
                    errorCode = Marshal.GetLastWin32Error();
                }

                if (ex != null)
                    throw ex;
                if (errorCode != 0 && errorCode != Interop.Errors.ERROR_NO_MORE_FILES)
                    throw Win32Marshal.GetExceptionForWin32Error(errorCode, fullPath);
            }

            r = Interop.Kernel32.RemoveDirectory(fullPath);

            if (!r)
            {
                errorCode = Marshal.GetLastWin32Error();
                if (errorCode == Interop.Errors.ERROR_FILE_NOT_FOUND) // A dubious error code.
                    errorCode = Interop.Errors.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 (errorCode == Interop.Errors.ERROR_ACCESS_DENIED)
                    throw new IOException(SR.Format(SR.UnauthorizedAccess_IODenied_Path, fullPath));

                // don't throw the DirectoryNotFoundException since this is a subdir and 
                // there could be a race condition between two Directory.Delete callers
                if (errorCode == Interop.Errors.ERROR_PATH_NOT_FOUND && !throwOnTopLevelDirectoryNotFound)
                    return;

                throw Win32Marshal.GetExceptionForWin32Error(errorCode, fullPath);
            }
        }