Exemple #1
0
        /*private FileSecurity GetSecurity(){
         *      // <TODO> !!!
         *      Type obTypeToGet = Type.GetType("System.Security.Principal.NTAccount");
         *      //return File.GetAccessControl(originalFileName).GetOwner(obTypeToGet).ToString
         *        System.IO.FileInfo fileInfo = new System.IO.FileInfo (fileName);
         *
         * return fileInfo.GetAccessControl();
         *      //Alphaleonis.Win32.Filesystem.FileInfo ff = new Alphaleonis.Win32.Filesystem.FileInfo(fileName);
         *      //Alphaleonis.Win32.Filesystem.FileSystemRights
         *
         *      //return 0;
         * }*/

        internal FileType GetKind(Alphaleonis.Win32.Filesystem.FileSystemEntryInfo fseInfo)
        {
            if (fseInfo.IsReparsePoint)
            {
                return(FileType.MountPoint);
            }
            else if (fseInfo.IsSymbolicLink)
            {
                return(FileType.Symlink);
            }
            else if (fseInfo.Attributes == Alphaleonis.Win32.Filesystem.FileAttributes.Offline)
            {
                return(FileType.Unsupported);
            }
            else if (fseInfo.Attributes.HasFlag(Alphaleonis.Win32.Filesystem.FileAttributes.Device))
            {
                return(FileType.BlockDevice);
            }
            else if (fseInfo.IsDirectory)
            {
                return(FileType.Directory);
            }
            else if (fseInfo.IsFile)
            {
                return(FileType.File);
            }
            else
            {
                Console.WriteLine("unsupported file type for " + fileName + ", attributes : " + fseInfo.Attributes.ToString());
            }
            return(FileType.Unsupported);
        }
Exemple #2
0
        internal static void DeleteEmptySubdirectoriesCore(FileSystemEntryInfo fileSystemEntryInfo, KernelTransaction transaction, string path, bool recursive, bool ignoreReadOnly, bool initialize, PathFormat pathFormat)
        {
            #region Setup

            if (pathFormat == PathFormat.RelativePath)
            {
                Path.CheckSupportedPathFormat(path, true, true);
            }

            if (fileSystemEntryInfo == null)
            {
                if (!File.ExistsCore(true, transaction, path, pathFormat))
                {
                    NativeError.ThrowException(Win32Errors.ERROR_PATH_NOT_FOUND, path);
                }

                fileSystemEntryInfo = File.GetFileSystemEntryInfoCore(true, transaction, Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck), false, pathFormat);
            }

            if (fileSystemEntryInfo == null)
            {
                throw new ArgumentNullException("path");
            }

            string pathLp = fileSystemEntryInfo.LongFullPath;

            #endregion // Setup

            // Ensure path is a directory.
            if (!fileSystemEntryInfo.IsDirectory)
            {
                throw new IOException(string.Format(CultureInfo.CurrentCulture, Resources.Target_Directory_Is_A_File, pathLp));
            }


            var dirEnumOptions = DirectoryEnumerationOptions.Folders;

            if (recursive)
            {
                dirEnumOptions |= DirectoryEnumerationOptions.Recursive;
            }

            foreach (var fsei in EnumerateFileSystemEntryInfosCore <FileSystemEntryInfo>(transaction, pathLp, Path.WildcardStarMatchAll, dirEnumOptions, PathFormat.LongFullPath))
            {
                DeleteEmptySubdirectoriesCore(fsei, transaction, null, recursive, ignoreReadOnly, false, PathFormat.LongFullPath);
            }


            if (!EnumerateFileSystemEntryInfosCore <string>(transaction, pathLp, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.LongFullPath).Any())
            {
                // Prevent deleting path itself.
                if (!initialize)
                {
                    DeleteDirectoryCore(fileSystemEntryInfo, transaction, null, false, ignoreReadOnly, true, PathFormat.LongFullPath);
                }
            }
        }
        private T NewFileSystemEntryType <T>(bool isFolder, FileSystemEntryInfo fsei, string fileName, string pathLp, NativeMethods.WIN32_FIND_DATA win32FindData)
        {
            // Determine yield, e.g. don't return files when only folders are requested and vice versa.
            if (null != FileSystemObjectType && (!(bool)FileSystemObjectType || !isFolder) && (!(bool)!FileSystemObjectType || isFolder))
            {
                return((T)(object)null);
            }


            // Determine yield.
            if (null != fileName && !(_nameFilter == null || _nameFilter != null && _nameFilter.IsMatch(fileName)))
            {
                return((T)(object)null);
            }


            if (null == fsei)
            {
                fsei = NewFilesystemEntry(pathLp, fileName, win32FindData);
            }


            // Return object instance FullPath property as string, optionally in long path format.

            return(AsString
            ? null == InclusionFilter || InclusionFilter(fsei)
               ? (T)(object)(AsLongPath ? fsei.LongFullPath : fsei.FullPath)
               : (T)(object)null


                   // Make sure the requested file system object type is returned.
                   // null = Return files and directories.
                   // true = Return only directories.
                   // false = Return only files.

            : null != InclusionFilter && !InclusionFilter(fsei)
               ? (T)(object)null

                   // Return object instance of type FileSystemInfo.

               : AsFileSystemInfo
                  ? (T)(object)(fsei.IsDirectory

                     ? (FileSystemInfo) new DirectoryInfo(Transaction, fsei.LongFullPath, PathFormat.LongFullPath)
            {
                EntryInfo = fsei
            }

                     : new FileInfo(Transaction, fsei.LongFullPath, PathFormat.LongFullPath)
            {
                EntryInfo = fsei
            })

                   // Return object instance of type FileSystemEntryInfo.

                  : (T)(object)fsei);
        }
        internal static void DeleteEmptySubdirectoriesCore(FileSystemEntryInfo fsEntryInfo, KernelTransaction transaction, string path, bool recursive, bool ignoreReadOnly, PathFormat pathFormat)
        {
            #region Setup

            if (null == fsEntryInfo)
            {
                if (pathFormat == PathFormat.RelativePath)
                {
                    Path.CheckSupportedPathFormat(path, true, true);
                }

                if (!File.ExistsCore(transaction, true, path, pathFormat))
                {
                    NativeError.ThrowException(Win32Errors.ERROR_PATH_NOT_FOUND, path);
                }

                fsEntryInfo = File.GetFileSystemEntryInfoCore(transaction, true, Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck), false, pathFormat);

                if (null == fsEntryInfo)
                {
                    return;
                }
            }

            #endregion // Setup


            // Ensure path is a directory.
            if (!fsEntryInfo.IsDirectory)
            {
                throw new IOException(string.Format(CultureInfo.InvariantCulture, Resources.Target_Directory_Is_A_File, fsEntryInfo.LongFullPath));
            }


            var dirs = new Stack <string>(1000);
            dirs.Push(fsEntryInfo.LongFullPath);

            while (dirs.Count > 0)
            {
                foreach (var fsei in EnumerateFileSystemEntryInfosCore <FileSystemEntryInfo>(true, transaction, dirs.Pop(), Path.WildcardStarMatchAll, null, DirectoryEnumerationOptions.ContinueOnException, null, PathFormat.LongFullPath))
                {
                    // Ensure the directory is empty.
                    if (IsEmptyCore(transaction, fsei.LongFullPath, pathFormat))
                    {
                        DeleteDirectoryCore(transaction, fsei, null, false, ignoreReadOnly, true, PathFormat.LongFullPath);
                    }

                    else if (recursive)
                    {
                        dirs.Push(fsei.LongFullPath);
                    }
                }
            }
        }
Exemple #5
0
        private T NewFileSystemEntryType <T>(bool isFolder, NativeMethods.WIN32_FIND_DATA win32FindData, string fileName, string pathLp)
        {
            // Determine yield, e.g. don't return files when only folders are requested and vice versa.
            if (null != FileSystemObjectType && (!(bool)FileSystemObjectType || !isFolder) && (!(bool)!FileSystemObjectType || isFolder))
            {
                return((T)(object)null);
            }

            // Determine yield.
            if (null != fileName && !(_nameFilter == null || (_nameFilter != null && _nameFilter.IsMatch(fileName))))
            {
                return((T)(object)null);
            }


            var fullPathLp = (IsRelativePath ? OriginalInputPath + Path.DirectorySeparator : pathLp) + (!Utils.IsNullOrWhiteSpace(fileName) ? fileName : string.Empty);


            // Return object instance FullPath property as string, optionally in long path format.
            if (AsString)
            {
                return((T)(object)(AsLongPath ? fullPathLp : Path.GetRegularPathCore(fullPathLp, GetFullPathOptions.None, false)));
            }


            // Make sure the requested file system object type is returned.
            // null = Return files and directories.
            // true = Return only directories.
            // false = Return only files.

            var fsei = new FileSystemEntryInfo(win32FindData)
            {
                FullPath = fullPathLp
            };

            return(AsFileSystemInfo
                   // Return object instance of type FileSystemInfo.
            ? (T)(object)(fsei.IsDirectory
               ? (FileSystemInfo)
                          new DirectoryInfo(Transaction, fsei.LongFullPath, PathFormat.LongFullPath)
            {
                EntryInfo = fsei
            }
               : new FileInfo(Transaction, fsei.LongFullPath, PathFormat.LongFullPath)
            {
                EntryInfo = fsei
            })

                   // Return object instance of type FileSystemEntryInfo.
            : (T)(object)fsei);
        }
Exemple #6
0
        public NTBackupFile(Alphaleonis.Win32.Filesystem.FileSystemEntryInfo fsi)
        {
            fileName  = fsi.FullPath;
            this.Name = fsi.FileName;
            fseInfo   = fsi;
            this.Kind = GetKind(fsi);

            /*this.FileSize = 0;
             * try{
             *      this.FileSize += GetSize ();
             * }
             * catch(Exception e){
             *      Logger.Append(Severity.ERROR, "Unable to get size of item "+SnapFullPath+" "+e.Message);
             *              throw(e);
             * }*/
            this.FileSize = fsi.FileSize;

            if (this.Kind == FileType.Symlink)
            {
                this.TargetName = fsi.VirtualFullPath;
            }
            if (this.Kind != FileType.Directory || this.Kind != FileType.Unsupported)
            {
                this.LastModifiedTime = Utilities.Utils.GetUtcUnixTime(fsi.LastModified);                 //fsi.LastModified.ToFileTimeUtc();
            }
            else
            {
                this.LastModifiedTime = DateTime.MaxValue.ToFileTimeUtc();
            }

            this.LastMetadataModifiedTime = 0;                             // dummy value for correctness of incrementals using filecompare
            this.CreateTime = Utilities.Utils.GetUtcUnixTime(fsi.Created); //fsi.Created.ToFileTimeUtc();

            GetHandleInfos();

            if (fseInfo.IsMountPoint || fseInfo.IsReparsePoint || fseInfo.IsSymbolicLink)
            {
                //this.TargetName = fseInfo.VirtualFullPath;
                Console.WriteLine("** Item " + fileName + " is a " + this.Kind + ", target=" + TargetName);
                //Console.WriteLine ("reparsepoint tag(s)="+fsi.ReparsePointTag.ToString());
            }
            if (this.Kind == FileType.Unsupported)
            {
                Console.WriteLine("unsupported file " + fileName + " with attributes " + fseInfo.Attributes.ToString());
            }
            this.Attributes = (int)fsi.Attributes;
            //wSecurity =  GetSecurity(); // unneeded as we save using BackupRead(), which includes security info
            //ownerUser = wSecurity.GetOwner(typeof(NTAccount)).;
            BlockMetadata = new FileBlockMetadata();
        }
        private T NewFileSystemEntryType <T>(NativeMethods.WIN32_FIND_DATA win32FindData, string fileName, string pathLp, bool isFolder)
        {
            // Determine yield.
            if (FileSystemObjectType != null && (!(bool)FileSystemObjectType || !isFolder) && (!(bool)!FileSystemObjectType || isFolder))
            {
                return((T)(object)null);
            }


            var fullPathLp = string.Format(CultureInfo.InvariantCulture, "{0}{1}", pathLp, fileName ?? string.Empty);


            // Return object instance FullPath property as string, optionally in long path format.
            if (AsString)
            {
                return((T)(object)(IsRelativePath
               ? fullPathLp
               : (AsLongPath ? fullPathLp : Path.GetRegularPathCore(fullPathLp, GetFullPathOptions.None, false))));
            }


            // Make sure the requested file system object type is returned.
            // null = Return files and directories.
            // true = Return only directories.
            // false = Return only files.

            var fsei = new FileSystemEntryInfo(win32FindData)
            {
                FullPath = !fullPathLp.StartsWith(Path.CurrentDirectoryPrefix, StringComparison.OrdinalIgnoreCase)
               ? fullPathLp
               : Path.CombineCore(false, InputPath, fileName)
            };


            return(AsFileSystemInfo
                   // Return object instance of type FileSystemInfo.
            ? (T)(object)(fsei.IsDirectory
               ? (FileSystemInfo)
                          new DirectoryInfo(Transaction, fsei.LongFullPath, PathFormat.LongFullPath)
            {
                EntryInfo = fsei
            }
               : new FileInfo(Transaction, fsei.LongFullPath, PathFormat.LongFullPath)
            {
                EntryInfo = fsei
            })

                   // Return object instance of type FileSystemEntryInfo.
            : (T)(object)fsei);
        }
Exemple #8
0
        protected void RefreshEntryInfo()
        {
            _entryInfo = File.GetFileSystemEntryInfoCore(Transaction, IsDirectory, LongFullName, true, PathFormat.LongFullPath);

            if (null == _entryInfo)
            {
                DataInitialised = -1;
            }

            else
            {
                DataInitialised    = 0;
                Win32AttributeData = new NativeMethods.WIN32_FILE_ATTRIBUTE_DATA(_entryInfo.Win32FindData);
            }
        }
Exemple #9
0
        internal static bool ExistsJunctionCore(KernelTransaction transaction, FileSystemEntryInfo fsEntryInfo, string junctionPath, PathFormat pathFormat)
        {
            if (null == fsEntryInfo)
            {
                if (pathFormat != PathFormat.LongFullPath)
                {
                    Path.CheckSupportedPathFormat(junctionPath, true, true);

                    junctionPath = Path.GetExtendedLengthPathCore(transaction, junctionPath, pathFormat, GetFullPathOptions.CheckInvalidPathChars | GetFullPathOptions.RemoveTrailingDirectorySeparator);

                    pathFormat = PathFormat.LongFullPath;
                }


                fsEntryInfo = File.GetFileSystemEntryInfoCore(transaction, true, junctionPath, true, pathFormat);
            }


            return(null != fsEntryInfo && fsEntryInfo.IsMountPoint);
        }
        private T NewFileSystemEntryType <T>(NativeMethods.WIN32_FIND_DATA win32FindData, string fullPathLp, bool isFolder)
        {
            // Determine yield.
            if (FileSystemObjectType != null && ((!(bool)FileSystemObjectType || !isFolder) && (!(bool)!FileSystemObjectType || isFolder)))
            {
                return((T)(object)null);
            }

            if (AsString)
            {
                // Return object instance FullPath property as string, optionally in long path format.
                return((T)(object)(AsLongPath ? fullPathLp : Path.GetRegularPathCore(fullPathLp, GetFullPathOptions.None)));
            }


            // Make sure the requested file system object type is returned.
            // null = Return files and directories.
            // true = Return only directories.
            // false = Return only files.

            var fsei = new FileSystemEntryInfo(win32FindData)
            {
                FullPath = fullPathLp
            };

            return(AsFileSystemInfo
                   // Return object instance of type FileSystemInfo.
            ? (T)(object)(fsei.IsDirectory
               ? (FileSystemInfo)
                          new DirectoryInfo(Transaction, fsei.LongFullPath, PathFormat.LongFullPath)
            {
                EntryInfo = fsei
            }
               : new FileInfo(Transaction, fsei.LongFullPath, PathFormat.LongFullPath)
            {
                EntryInfo = fsei
            })

                   // Return object instance of type FileSystemEntryInfo.
            : (T)(object)fsei);
        }
Exemple #11
0
        internal static void DeleteJunctionCore(KernelTransaction transaction, FileSystemEntryInfo fsEntryInfo, string junctionPath, bool removeDirectory, PathFormat pathFormat)
        {
            if (null == fsEntryInfo)
            {
                if (pathFormat != PathFormat.LongFullPath)
                {
                    Path.CheckSupportedPathFormat(junctionPath, true, true);

                    junctionPath = Path.GetExtendedLengthPathCore(transaction, junctionPath, pathFormat, GetFullPathOptions.CheckInvalidPathChars | GetFullPathOptions.RemoveTrailingDirectorySeparator);

                    pathFormat = PathFormat.LongFullPath;
                }


                fsEntryInfo = File.GetFileSystemEntryInfoCore(transaction, true, junctionPath, false, pathFormat);

                if (!fsEntryInfo.IsMountPoint)
                {
                    throw new NotAReparsePointException(string.Format(CultureInfo.InvariantCulture, Resources.Directory_Is_Not_A_MountPoint, fsEntryInfo.LongFullPath), (int)Win32Errors.ERROR_NOT_A_REPARSE_POINT);
                }
            }


            pathFormat = PathFormat.LongFullPath;


            // Remove the directory junction.
            using (var safeHandle = OpenDirectoryJunction(transaction, fsEntryInfo.LongFullPath, pathFormat))
                Device.DeleteDirectoryJunction(safeHandle);


            // Optionally the folder itself, which should and must be empty.
            if (removeDirectory)
            {
                DeleteDirectoryCore(transaction, fsEntryInfo, null, false, false, true, pathFormat);
            }
        }
Exemple #12
0
 static internal extern SafeFindFileHandle FindFirstFileExW([In] string lpFileName, [In] FINDEX_INFO_LEVELS fInfoLevelId, [In, Out] FileSystemEntryInfo lpFindFileData, [In] FINDEX_SEARCH_OPS fSearchOp, [In] IntPtr lpSearchFilter, [In] FINDEX_FLAGS dwAdditionalFlags);
Exemple #13
0
      internal static void DeleteDirectoryInternal(FileSystemEntryInfo fileSystemEntryInfo, KernelTransaction transaction, string path, bool recursive, bool ignoreReadOnly, bool requireEmpty, bool continueOnNotExist, PathFormat pathFormat)
      {
         #region Setup

         if (pathFormat == PathFormat.RelativePath)
            Path.CheckValidPath(path, true, true);

         if (fileSystemEntryInfo == null)
         {
            // MSDN: .NET 3.5+: DirectoryNotFoundException:
            // Path does not exist or could not be found.
            // Path refers to a file instead of a directory.
            // The specified path is invalid (for example, it is on an unmapped drive). 

            fileSystemEntryInfo = File.GetFileSystemEntryInfoInternal(transaction,
               Path.GetExtendedLengthPathInternal(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator),
                  continueOnNotExist, pathFormat);
         }

         if (fileSystemEntryInfo == null)
            return;

         string pathLp = fileSystemEntryInfo.LongFullPath;

         #endregion // Setup

         // Do not follow mount points nor symbolic links, but do delete the reparse point itself.

         // If directory is reparse point, disable recursion.
         if (recursive && fileSystemEntryInfo.IsReparsePoint)
            recursive = false;


         // Check to see if this is a mount point, and unmount it.
         if (fileSystemEntryInfo.IsMountPoint)
         {
            int lastError = Volume.DeleteVolumeMountPointInternal(pathLp, true);

            if (lastError != Win32Errors.ERROR_SUCCESS && lastError != Win32Errors.ERROR_PATH_NOT_FOUND)
               NativeError.ThrowException(lastError, pathLp);

            // Now it is safe to delete the actual directory.
         }


         if (recursive)
         {
            // Enumerate all file system objects.
            foreach (FileSystemEntryInfo fsei in EnumerateFileSystemEntryInfosInternal<FileSystemEntryInfo>(transaction, pathLp, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.LongFullPath))
            {
               if (fsei.IsDirectory)
                  DeleteDirectoryInternal(fsei, transaction, null, true, ignoreReadOnly, requireEmpty, true, PathFormat.LongFullPath);
               else
                  File.DeleteFileInternal(transaction, fsei.LongFullPath, ignoreReadOnly, PathFormat.LongFullPath);
            }
         }

         #region Remove

      startRemoveDirectory:

         if (!(transaction == null || !NativeMethods.IsAtLeastWindowsVista

            // RemoveDirectory() / RemoveDirectoryTransacted()
            // In the ANSI version of this function, the name is limited to MAX_PATH characters.
            // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.
            // 2014-09-09: MSDN confirms LongPath usage.

            // RemoveDirectory on a symbolic link will remove the link itself.

            ? NativeMethods.RemoveDirectory(pathLp)
            : NativeMethods.RemoveDirectoryTransacted(pathLp, transaction.SafeHandle)))
         {
            int lastError = Marshal.GetLastWin32Error();
            switch ((uint)lastError)
            {
               case Win32Errors.ERROR_DIR_NOT_EMPTY:
                  if (requireEmpty)
                     // MSDN: .NET 3.5+: IOException: The directory specified by path is not an empty directory. 
                     throw new DirectoryNotEmptyException(pathLp);

                  goto startRemoveDirectory;


               case Win32Errors.ERROR_DIRECTORY:
                  // MSDN: .NET 3.5+: DirectoryNotFoundException: Path refers to a file instead of a directory.
                  if (File.ExistsInternal(false, transaction, pathLp, PathFormat.LongFullPath))
                     throw new DirectoryNotFoundException(String.Format(CultureInfo.CurrentCulture, "({0}) {1}",
                        Win32Errors.ERROR_INVALID_PARAMETER, String.Format(CultureInfo.CurrentCulture, Resources.FileExistsWithSameNameSpecifiedByPath, pathLp)));
                  break;


               case Win32Errors.ERROR_PATH_NOT_FOUND:
                  if (continueOnNotExist)
                     return;
                  break;

               case Win32Errors.ERROR_SHARING_VIOLATION:
                  // MSDN: .NET 3.5+: IOException: The directory is being used by another process or there is an open handle on the directory.
                  NativeError.ThrowException(lastError, pathLp);
                  break;

               case Win32Errors.ERROR_ACCESS_DENIED:
                  NativeMethods.Win32FileAttributeData data = new NativeMethods.Win32FileAttributeData();
                  int dataInitialised = File.FillAttributeInfoInternal(transaction, pathLp, ref data, false, true);

                  if (data.FileAttributes != (FileAttributes)(-1))
                  {
                     if ((data.FileAttributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                     {
                        // MSDN: .NET 3.5+: IOException: The directory specified by path is read-only.

                        if (ignoreReadOnly)
                        {
                           // Reset directory attributes.
                           File.SetAttributesInternal(true, transaction, pathLp, FileAttributes.Normal, true, PathFormat.LongFullPath);
                           goto startRemoveDirectory;
                        }

                        // MSDN: .NET 3.5+: IOException: The directory is read-only.
                        throw new DirectoryReadOnlyException(pathLp);
                     }
                  }

                  if (dataInitialised == Win32Errors.ERROR_SUCCESS)
                     // MSDN: .NET 3.5+: UnauthorizedAccessException: The caller does not have the required permission.
                     NativeError.ThrowException(lastError, pathLp);

                  break;
            }

            // MSDN: .NET 3.5+: IOException:
            // A file with the same name and location specified by path exists.
            // The directory specified by path is read-only, or recursive is false and path is not an empty directory. 
            // The directory is the application's current working directory. 
            // The directory contains a read-only file.
            // The directory is being used by another process.

            NativeError.ThrowException(lastError, pathLp);
         }

         #endregion // Remove
      }
      internal static void DeleteEmptySubdirectoriesInternal(FileSystemEntryInfo fileSystemEntryInfo, KernelTransaction transaction, string path, bool recursive, bool ignoreReadOnly, bool initialize, PathFormat pathFormat)
      {
         #region Setup

         if (pathFormat == PathFormat.RelativePath)
            Path.CheckValidPath(path, true, true);

         if (fileSystemEntryInfo == null)
         {
            if (!File.ExistsInternal(true, transaction, path, pathFormat))
               NativeError.ThrowException(Win32Errors.ERROR_PATH_NOT_FOUND, path);

            fileSystemEntryInfo = File.GetFileSystemEntryInfoInternal(transaction,
               Path.GetExtendedLengthPathInternal(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck)
               , false, pathFormat);
         }

         if (fileSystemEntryInfo == null)
            throw new ArgumentNullException("path");

         string pathLp = fileSystemEntryInfo.LongFullPath;

         #endregion // Setup

         // Ensure path is a directory.
         if (!fileSystemEntryInfo.IsDirectory)
            throw new IOException(String.Format(CultureInfo.CurrentCulture, Resources.FileExistsWithSameNameSpecifiedByPath, pathLp));

         var dirEnumOptions = DirectoryEnumerationOptions.Folders;
         if (recursive)
            dirEnumOptions |= DirectoryEnumerationOptions.Recursive;

         foreach (var fsei in EnumerateFileSystemEntryInfosInternal<FileSystemEntryInfo>(transaction, pathLp, Path.WildcardStarMatchAll, dirEnumOptions, PathFormat.LongFullPath))
            DeleteEmptySubdirectoriesInternal(fsei, transaction, null, recursive, ignoreReadOnly, false, PathFormat.LongFullPath);


         if (!EnumerateFileSystemEntryInfosInternal<string>(transaction, pathLp, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.LongFullPath).Any())
         {
            // Prevent deleting path itself.
            if (!initialize)
               DeleteDirectoryInternal(fileSystemEntryInfo, transaction, null, false, ignoreReadOnly, true, true, PathFormat.LongFullPath);
         }
      }
        internal static void DeleteDirectoryCore(KernelTransaction transaction, FileSystemEntryInfo fsEntryInfo, string path, bool recursive, bool ignoreReadOnly, bool continueOnNotFound, PathFormat pathFormat)
        {
            if (null == fsEntryInfo)
            {
                // MSDN: .NET 3.5+: DirectoryNotFoundException:
                // Path does not exist or could not be found.
                // Path refers to a file instead of a directory.
                // The specified path is invalid (for example, it is on an unmapped drive).

                if (pathFormat == PathFormat.RelativePath)
                {
                    Path.CheckSupportedPathFormat(path, true, true);
                }

                fsEntryInfo = File.GetFileSystemEntryInfoCore(transaction, true, Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator), continueOnNotFound, pathFormat);

                if (null == fsEntryInfo)
                {
                    return;
                }
            }

            pathFormat = PathFormat.LongFullPath;


            // Do not follow mount points nor symbolic links, but do delete the reparse point itself.
            // If directory is reparse point, disable recursion.

            if (recursive && !fsEntryInfo.IsReparsePoint)
            {
                var dirs = new Stack <string>(1000);

                foreach (var fsei in EnumerateFileSystemEntryInfosCore <FileSystemEntryInfo>(null, transaction, fsEntryInfo.LongFullPath, Path.WildcardStarMatchAll, SearchOption.AllDirectories, null, null, pathFormat))
                {
                    if (fsei.IsDirectory)
                    {
                        // Check to see if this is a mount point, and unmount it.
                        // Now it is safe to delete the actual directory.
                        if (fsei.IsMountPoint)
                        {
                            DeleteJunctionCore(transaction, fsei, null, false, pathFormat);
                        }
                        //Volume.DeleteVolumeMountPointCore(transaction, fsei.LongFullPath, false, true, pathFormat);

                        dirs.Push(fsei.LongFullPath);
                    }

                    else
                    {
                        File.DeleteFileCore(transaction, fsei.LongFullPath, ignoreReadOnly, pathFormat);
                    }
                }


                while (dirs.Count > 0)
                {
                    DeleteDirectoryCore(transaction, dirs.Pop(), ignoreReadOnly, continueOnNotFound);
                }
            }


            // Check to see if this is a mount point, and unmount it.
            // Now it is safe to delete the actual directory.
            if (fsEntryInfo.IsMountPoint)
            {
                DeleteJunctionCore(transaction, fsEntryInfo, null, false, pathFormat);
            }
            //Volume.DeleteVolumeMountPointCore(transaction, fsEntryInfo.LongFullPath, false, true, pathFormat);

            DeleteDirectoryCore(transaction, fsEntryInfo.LongFullPath, ignoreReadOnly, continueOnNotFound);
        }
Exemple #16
0
        internal static void DeleteDirectoryCore(FileSystemEntryInfo fileSystemEntryInfo, KernelTransaction transaction, string path, bool recursive, bool ignoreReadOnly, bool requireEmpty, bool continueOnNotExist, PathFormat pathFormat)
        {
            #region Setup

            if (pathFormat == PathFormat.RelativePath)
            {
                Path.CheckSupportedPathFormat(path, true, true);
            }

            if (fileSystemEntryInfo == null)
            {
                // MSDN: .NET 3.5+: DirectoryNotFoundException:
                // Path does not exist or could not be found.
                // Path refers to a file instead of a directory.
                // The specified path is invalid (for example, it is on an unmapped drive).

                fileSystemEntryInfo = File.GetFileSystemEntryInfoCore(true, transaction,
                                                                      Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator),
                                                                      continueOnNotExist, pathFormat);
            }

            if (fileSystemEntryInfo == null)
            {
                return;
            }

            string pathLp = fileSystemEntryInfo.LongFullPath;

            #endregion // Setup

            // Do not follow mount points nor symbolic links, but do delete the reparse point itself.

            // If directory is reparse point, disable recursion.
            if (recursive && fileSystemEntryInfo.IsReparsePoint)
            {
                recursive = false;
            }


            // Check to see if this is a mount point, and unmount it.
            if (fileSystemEntryInfo.IsMountPoint)
            {
                int lastError = Volume.DeleteVolumeMountPointCore(pathLp, true);

                if (lastError != Win32Errors.ERROR_SUCCESS && lastError != Win32Errors.ERROR_PATH_NOT_FOUND)
                {
                    NativeError.ThrowException(lastError, pathLp);
                }

                // Now it is safe to delete the actual directory.
            }


            if (recursive)
            {
                // Enumerate all file system objects.
                foreach (var fsei in EnumerateFileSystemEntryInfosCore <FileSystemEntryInfo>(transaction, pathLp, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.LongFullPath))
                {
                    if (fsei.IsDirectory)
                    {
                        DeleteDirectoryCore(fsei, transaction, null, true, ignoreReadOnly, requireEmpty, true, PathFormat.LongFullPath);
                    }
                    else
                    {
                        File.DeleteFileCore(transaction, fsei.LongFullPath, ignoreReadOnly, PathFormat.LongFullPath);
                    }
                }
            }

            #region Remove

startRemoveDirectory:

            if (!(transaction == null || !NativeMethods.IsAtLeastWindowsVista

                  // RemoveDirectory() / RemoveDirectoryTransacted()
                  // In the ANSI version of this function, the name is limited to MAX_PATH characters.
                  // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.
                  // 2014-09-09: MSDN confirms LongPath usage.

                  // RemoveDirectory on a symbolic link will remove the link itself.

            ? NativeMethods.RemoveDirectory(pathLp)
            : NativeMethods.RemoveDirectoryTransacted(pathLp, transaction.SafeHandle)))
            {
                int lastError = Marshal.GetLastWin32Error();
                switch ((uint)lastError)
                {
                case Win32Errors.ERROR_DIR_NOT_EMPTY:
                    if (requireEmpty)
                    {
                        // MSDN: .NET 3.5+: IOException: The directory specified by path is not an empty directory.
                        throw new DirectoryNotEmptyException(pathLp);
                    }

                    goto startRemoveDirectory;


                case Win32Errors.ERROR_DIRECTORY:
                    // MSDN: .NET 3.5+: DirectoryNotFoundException: Path refers to a file instead of a directory.
                    if (File.ExistsCore(false, transaction, pathLp, PathFormat.LongFullPath))
                    {
                        throw new DirectoryNotFoundException(string.Format(CultureInfo.CurrentCulture, "({0}) {1}", Win32Errors.ERROR_INVALID_PARAMETER, string.Format(CultureInfo.CurrentCulture, Resources.Target_Directory_Is_A_File, pathLp)));
                    }
                    break;


                case Win32Errors.ERROR_PATH_NOT_FOUND:
                    if (continueOnNotExist)
                    {
                        return;
                    }
                    break;

                case Win32Errors.ERROR_SHARING_VIOLATION:
                    // MSDN: .NET 3.5+: IOException: The directory is being used by another process or there is an open handle on the directory.
                    NativeError.ThrowException(lastError, pathLp);
                    break;

                case Win32Errors.ERROR_ACCESS_DENIED:
                    var data            = new NativeMethods.WIN32_FILE_ATTRIBUTE_DATA();
                    int dataInitialised = File.FillAttributeInfoCore(transaction, pathLp, ref data, false, true);

                    if (data.dwFileAttributes != (FileAttributes)(-1))
                    {
                        if ((data.dwFileAttributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                        {
                            // MSDN: .NET 3.5+: IOException: The directory specified by path is read-only.

                            if (ignoreReadOnly)
                            {
                                // Reset directory attributes.
                                File.SetAttributesCore(true, transaction, pathLp, FileAttributes.Normal, true, PathFormat.LongFullPath);
                                goto startRemoveDirectory;
                            }

                            // MSDN: .NET 3.5+: IOException: The directory is read-only.
                            throw new DirectoryReadOnlyException(pathLp);
                        }
                    }

                    if (dataInitialised == Win32Errors.ERROR_SUCCESS)
                    {
                        // MSDN: .NET 3.5+: UnauthorizedAccessException: The caller does not have the required permission.
                        NativeError.ThrowException(lastError, pathLp);
                    }

                    break;
                }

                // MSDN: .NET 3.5+: IOException:
                // A file with the same name and location specified by path exists.
                // The directory specified by path is read-only, or recursive is false and path is not an empty directory.
                // The directory is the application's current working directory.
                // The directory contains a read-only file.
                // The directory is being used by another process.

                NativeError.ThrowException(lastError, pathLp);
            }

            #endregion // Remove
        }
Exemple #17
0
 static internal extern bool FindNextFileW([In] SafeFindFileHandle hFindFile, [In, Out] FileSystemEntryInfo lpFindFileData);