瀏覽代碼

Update of AlphaFS to latest version

tags/4.2.4
Raimund Andée [MSFT] 7 年之前
父節點
當前提交
c5d00cc7cc
共有 51 個文件被更改,包括 792 次插入393 次删除
  1. +63
    -0
      .gitattributes
  2. +245
    -0
      .gitignore
  3. +2
    -2
      AlphaFS/AlphaFS.csproj
  4. +1
    -3
      AlphaFS/AssemblyVersionInfo.cs
  5. +0
    -2
      AlphaFS/Filesystem/CopyMoveProgressRoutine.cs
  6. +0
    -12
      AlphaFS/Filesystem/CopyMoveResult.cs
  7. +83
    -74
      AlphaFS/Filesystem/Directory Class/Directory.CopyMove.cs
  8. +71
    -66
      AlphaFS/Filesystem/Directory Class/Directory.Delete.cs
  9. +165
    -43
      AlphaFS/Filesystem/Directory Class/Directory.DeleteEmptySubdirectories.cs
  10. +5
    -1
      AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.CreateSubdirectory.cs
  11. +3
    -3
      AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.Delete.cs
  12. +3
    -3
      AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.DeleteEmptySubdirectories.cs
  13. +4
    -4
      AlphaFS/Filesystem/Enumerations/CopyMoveProgressResult.cs
  14. +1
    -1
      AlphaFS/Filesystem/Enumerations/DiGetClassFlags.cs
  15. +1
    -1
      AlphaFS/Filesystem/Enumerations/DosDeviceAttributes.cs
  16. +1
    -1
      AlphaFS/Filesystem/Enumerations/ExtendedFileAttributes.cs
  17. +1
    -1
      AlphaFS/Filesystem/Enumerations/FileInfoByHandleClass.cs
  18. +1
    -1
      AlphaFS/Filesystem/Enumerations/SymbolicLinkType.cs
  19. +3
    -6
      AlphaFS/Filesystem/Exceptions/TransactionException.cs
  20. +36
    -44
      AlphaFS/Filesystem/File Class/File.CopyMove.cs
  21. +1
    -1
      AlphaFS/Filesystem/File Class/File.CreateHardlink.cs
  22. +1
    -1
      AlphaFS/Filesystem/File Class/File.CreateSymbolicLink.cs
  23. +1
    -1
      AlphaFS/Filesystem/File Class/File.Delete.cs
  24. +1
    -1
      AlphaFS/Filesystem/File Class/File.EncryptDecrypt.cs
  25. +1
    -1
      AlphaFS/Filesystem/File Class/File.GetHash.cs
  26. +1
    -1
      AlphaFS/Filesystem/File Class/File.Replace.cs
  27. +12
    -16
      AlphaFS/Filesystem/File Class/File.SetAttributes.cs
  28. +2
    -2
      AlphaFS/Filesystem/FileInfo Class/FileInfo.Replace.cs
  29. +4
    -4
      AlphaFS/Filesystem/FileSystemInfo.cs
  30. +12
    -12
      AlphaFS/Filesystem/Native Methods/NativeMethods.VolumeManagement.cs
  31. +1
    -1
      AlphaFS/Filesystem/Native Structures/FILETIME.cs
  32. +1
    -1
      AlphaFS/Filesystem/Path Class/Path.Constants.cs
  33. +3
    -4
      AlphaFS/Filesystem/Path Class/Path.GetComponents.cs
  34. +1
    -4
      AlphaFS/Filesystem/Shell32.cs
  35. +1
    -1
      AlphaFS/Filesystem/Volume.cs
  36. +1
    -1
      AlphaFS/Network/Enumerations/ResourceType.cs
  37. +1
    -1
      AlphaFS/Network/Enumerations/ShareInfoLevel.cs
  38. +1
    -1
      AlphaFS/Network/Enumerations/ShareResourceTypes.cs
  39. +2
    -2
      AlphaFS/Network/Host Class/DistributedFileSystem.cs
  40. +1
    -2
      AlphaFS/Network/Host Class/EnumerateDrives.cs
  41. +1
    -1
      AlphaFS/Network/Host Class/EnumerateOpenResources.cs
  42. +12
    -15
      AlphaFS/Network/Host Class/ServerMessageBlock.cs
  43. +0
    -1
      AlphaFS/Network/Native Methods/NativeMethods.DistributedFileSystem.cs
  44. +1
    -1
      AlphaFS/Resources.Designer.cs
  45. +2
    -3
      AlphaFS/SafeNativeMemoryBufferHandle.cs
  46. +9
    -9
      AlphaFS/Security/Crc64.cs
  47. +16
    -24
      AlphaFS/Security/InternalPrivilegeEnabler.cs
  48. +1
    -1
      AlphaFS/Security/Privilege.cs
  49. +10
    -10
      AlphaFS/Win32Errors.cs
  50. +1
    -1
      AlphaFS/app.config
  51. +1
    -1
      NTFSSecurity/NTFSSecurity.csproj

+ 63
- 0
.gitattributes 查看文件

@@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto

###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp

###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary

###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary

###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

+ 245
- 0
.gitignore 查看文件

@@ -0,0 +1,245 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
[Xx]64/
[Xx]86/
[Bb]uild/
bld/
[Bb]in/
[Oo]bj/

# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

# NUNIT
*.VisualState.xml
TestResult.xml

# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c

# DNX
project.lock.json
artifacts/

*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

# Chutzpah Test files
_Chutzpah*

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db

# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap

# TFS 2012 Local Workspace
$tf/

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# JustCode is a .NET coding add-in
.JustCode

# TeamCity is a build add-in
_TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover

# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*

# MightyMoose
*.mm.*
AutoTest.Net/

# Web workbench (sass)
.sass-cache/

# Installshield output folder
[Ee]xpress/

# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

# Click-Once directory
publish/

# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml

# TODO: Un-comment the next line if you do not want to checkin
# your web deploy settings because they may include unencrypted
# passwords
#*.pubxml
*.publishproj

# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets

# Microsoft Azure Build Output
csx/
*.build.csdef

# Microsoft Azure Emulator
ecf/
rcf/

# Microsoft Azure ApplicationInsights config file
ApplicationInsights.config

# Windows Store app package directory
AppPackages/
BundleArtifacts/

# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/

# Others
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs

# RIA/Silverlight projects
Generated_Code/

# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm

# SQL Server files
*.mdf
*.ldf

# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings

# Microsoft Fakes
FakesAssemblies/

# GhostDoc plugin setting file
*.GhostDoc.xml

# Node.js Tools for Visual Studio
.ntvs_analysis.dat

# Visual Studio 6 build log
*.plg

# Visual Studio 6 workspace options file
*.opt

# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions

# LightSwitch generated files
GeneratedArtifacts/
ModelManifest.xml

# Paket dependency manager
.paket/paket.exe

# FAKE - F# Make
.fake/

+ 2
- 2
AlphaFS/AlphaFS.csproj 查看文件

@@ -14,7 +14,7 @@
<AssemblyOriginatorKeyFile>..\AlphaFS.snk</AssemblyOriginatorKeyFile>
<CodeAnalysisRuleSet>AlphaFS.ruleset</CodeAnalysisRuleSet>
<DelaySign>false</DelaySign>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -387,7 +387,7 @@
-->
<ProjectExtensions>
<VisualStudio>
<UserProperties StartDate="20080813" AssemblyFileVersion="0" AssemblyVersion="0" Reset="1" />
<UserProperties Reset="1" AssemblyVersion="0" AssemblyFileVersion="0" StartDate="20080813" />
</VisualStudio>
</ProjectExtensions>
</Project>

+ 1
- 3
AlphaFS/AssemblyVersionInfo.cs 查看文件

@@ -19,8 +19,6 @@
* THE SOFTWARE.
*/
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Resources;

[assembly: AssemblyCompany("")]
@@ -29,7 +27,7 @@ using System.Resources;
[assembly: AssemblyTrademark("")]

[assembly: AssemblyVersion("2.1.0.0")]
[assembly: AssemblyFileVersion("2.1.0.0")]
[assembly: AssemblyFileVersion("2.1.2.0")]
[assembly: AssemblyInformationalVersion("2.0")]
[assembly: NeutralResourcesLanguageAttribute("en-US")]


+ 0
- 2
AlphaFS/Filesystem/CopyMoveProgressRoutine.cs 查看文件

@@ -19,8 +19,6 @@
* THE SOFTWARE.
*/

using System;

namespace Alphaleonis.Win32.Filesystem
{
/// <summary>Callback used by CopyFileXxx and MoveFileXxx to report progress about the copy/move operation.</summary>


+ 0
- 12
AlphaFS/Filesystem/CopyMoveResult.cs 查看文件

@@ -19,9 +19,6 @@
* THE SOFTWARE.
*/

using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;

namespace Alphaleonis.Win32.Filesystem
{
/// <summary>Class for CopyMoveResult that contains the results for the Copy or Move action.</summary>
@@ -46,15 +43,6 @@ namespace Alphaleonis.Win32.Filesystem
public int ErrorCode { get; internal set; }


/// <summary>The error message from the <see cref="ErrorCode"/> that was encountered during the Copy or Move action.</summary>
/// <value>A message describing the error.</value>
[SuppressMessage("Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")]
public string ErrorMessage
{
get { return new Win32Exception(ErrorCode).Message; }
}


/// <summary>When true indicates that the Copy or Move action was canceled.</summary>
/// <value><see langword="true"/> when the Copy/Move action was canceled. Otherwise <see langword="false"/>.</value>
public bool IsCanceled { get; internal set; }


+ 83
- 74
AlphaFS/Filesystem/Directory Class/Directory.CopyMove.cs 查看文件

@@ -20,6 +20,7 @@
*/

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Security;
@@ -804,10 +805,16 @@ namespace Alphaleonis.Win32.Filesystem

var sourcePathLp = sourcePath;
var destinationPathLp = destinationPath;
var skipPathChecks = pathFormat == PathFormat.LongFullPath;
var emulateMove = false;

// Determine Copy or Move action.
var isCopy = File.DetermineIsCopy(copyOptions, moveOptions);
var isMove = !isCopy;

if (!skipPathChecks)
var cmr = copyMoveResult ?? new CopyMoveResult(sourcePath, destinationPath, false, (int) Win32Errors.ERROR_SUCCESS);


if (pathFormat != PathFormat.LongFullPath)
{
Path.CheckSupportedPathFormat(sourcePathLp, true, true);
Path.CheckSupportedPathFormat(destinationPathLp, true, true);
@@ -825,74 +832,65 @@ namespace Alphaleonis.Win32.Filesystem
// MSDN: .NET3.5+: IOException: The sourceDirName and destDirName parameters refer to the same file or directory.
if (sourcePathLp.Equals(destinationPathLp, StringComparison.OrdinalIgnoreCase))
NativeError.ThrowException(Win32Errors.ERROR_SAME_DRIVE, destinationPathLp);
}


var emulateMove = false;

// Determine Copy or Move action.
var isCopy = File.DetermineIsCopy(copyOptions, moveOptions);
var isMove = !isCopy;

var cmr = copyMoveResult ?? new CopyMoveResult(sourcePathLp, destinationPathLp, false, (int) Win32Errors.ERROR_SUCCESS);


// Execute once only.
if (!skipPathChecks && isMove)
{
// Compare the root part of both paths.
var equalRootPaths = Path.GetPathRoot(sourcePathLp, false).Equals(Path.GetPathRoot(destinationPathLp, false), StringComparison.OrdinalIgnoreCase);
// Execute once only.
if (isMove)
{
// Compare the root part of both paths.
var equalRootPaths = Path.GetPathRoot(sourcePathLp, false).Equals(Path.GetPathRoot(destinationPathLp, false), StringComparison.OrdinalIgnoreCase);

// Method Volume.IsSameVolume() returns true when both paths refer to the same volume, even if one of the paths is a UNC path.
// For example, src = C:\TempSrc and dst = \\localhost\C$\TempDst
var isSameVolume = equalRootPaths || Volume.IsSameVolume(sourcePathLp, destinationPathLp);
// Method Volume.IsSameVolume() returns true when both paths refer to the same volume, even if one of the paths is a UNC path.
// For example, src = C:\TempSrc and dst = \\localhost\C$\TempDst
var isSameVolume = equalRootPaths || Volume.IsSameVolume(sourcePathLp, destinationPathLp);

isMove = isSameVolume && equalRootPaths;
isMove = isSameVolume && equalRootPaths;

if (!isMove)
{
// A Move() can be emulated by using Copy() and Delete(), but only if the CopyAllowed flag is set.
isMove = ((MoveOptions) moveOptions & MoveOptions.CopyAllowed) != 0;

// MSDN: .NET3.5+: IOException: An attempt was made to move a directory to a different volume.
if (!isMove)
NativeError.ThrowException(Win32Errors.ERROR_NOT_SAME_DEVICE, sourcePathLp, destinationPathLp);
}
{
// A Move() can be emulated by using Copy() and Delete(), but only if the CopyAllowed flag is set.
isMove = ((MoveOptions) moveOptions & MoveOptions.CopyAllowed) != 0;

// MSDN: .NET3.5+: IOException: An attempt was made to move a directory to a different volume.
if (!isMove)
NativeError.ThrowException(Win32Errors.ERROR_NOT_SAME_DEVICE, sourcePathLp, destinationPathLp);
}

// The NativeMethod.MoveFileXxx() methods fail when:
// - A directory is being moved;
// - One of the paths is a UNC path, even though both paths refer to the same volume.
// For example, src = C:\TempSrc and dst = \\localhost\C$\TempDst
if (isMove)
{
var srcIsUncPath = Path.IsUncPathCore(sourcePathLp, false, false);
var dstIsUncPath = Path.IsUncPathCore(destinationPathLp, false, false);

isMove = srcIsUncPath && dstIsUncPath;
if (!isMove)
isMove = !srcIsUncPath && !dstIsUncPath;
}
// The NativeMethod.MoveFileXxx() methods fail when:
// - A directory is being moved;
// - One of the paths is a UNC path, even though both paths refer to the same volume.
// For example, src = C:\TempSrc and dst = \\localhost\C$\TempDst
if (isMove)
{
var srcIsUncPath = Path.IsUncPathCore(sourcePathLp, false, false);
var dstIsUncPath = Path.IsUncPathCore(destinationPathLp, false, false);

isMove = srcIsUncPath && dstIsUncPath;
if (!isMove)
isMove = !srcIsUncPath && !dstIsUncPath;
}

isMove = isMove && isSameVolume && equalRootPaths;

isMove = isMove && isSameVolume && equalRootPaths;

// Emulate Move().
if (!isMove)
{
emulateMove = true;

moveOptions = null;
// Emulate Move().
if (!isMove)
{
emulateMove = true;

moveOptions = null;

isCopy = true;
copyOptions = CopyOptions.FailIfExists;
isCopy = true;
copyOptions = CopyOptions.FailIfExists;
}
}
}
#endregion // Setup

#region Copy

@@ -900,45 +898,56 @@ namespace Alphaleonis.Win32.Filesystem
{
CreateDirectoryCore(transaction, destinationPathLp, null, null, false, PathFormat.LongFullPath);

foreach (var fsei in EnumerateFileSystemEntryInfosCore<FileSystemEntryInfo>(transaction, sourcePathLp, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.LongFullPath))
var dirs = new Queue<string>(1000);
dirs.Enqueue(sourcePathLp);
while (dirs.Count > 0)
{
var newDestinationPathLp = Path.CombineCore(false, destinationPathLp, fsei.FileName);

cmr = fsei.IsDirectory
? CopyMoveCore(transaction, fsei.LongFullPath, newDestinationPathLp, copyOptions, moveOptions, progressHandler, userProgressData, cmr, PathFormat.LongFullPath)
: File.CopyMoveCore(false, transaction, fsei.LongFullPath, newDestinationPathLp, false, copyOptions, moveOptions, progressHandler, userProgressData, cmr, PathFormat.LongFullPath);

var srcLp = dirs.Dequeue();
var dstLp = srcLp.Replace(sourcePathLp, destinationPathLp);

if (cmr.ErrorCode == Win32Errors.ERROR_SUCCESS)
foreach (var fsei in EnumerateFileSystemEntryInfosCore<FileSystemEntryInfo>(transaction, srcLp, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.LongFullPath))
{
var newDestinationPathLp = Path.CombineCore(false, dstLp, fsei.FileName);

if (fsei.IsDirectory)
{
CreateDirectoryCore(transaction, newDestinationPathLp, null, null, false, PathFormat.LongFullPath);

dirs.Enqueue(fsei.LongFullPath);
cmr.TotalFolders++;
else

continue;
}


cmr = File.CopyMoveCore(false, transaction, fsei.LongFullPath, newDestinationPathLp, false, copyOptions, moveOptions, progressHandler, userProgressData, cmr, PathFormat.LongFullPath);

if (cmr.ErrorCode == Win32Errors.ERROR_SUCCESS)
{
cmr.TotalFiles++;
cmr.TotalBytes += fsei.FileSize;
}

// Remove the folder or file when copying was successful.
if (emulateMove)
{
if (fsei.IsDirectory)
DeleteDirectoryCore(fsei, transaction, null, true, true, true, PathFormat.LongFullPath);

// Remove the folder or file when copying was successful.
if (emulateMove)
{
if (fsei.IsDirectory)
DeleteDirectoryCore(fsei, transaction, null, true, true, false, true, PathFormat.LongFullPath);
else
File.DeleteFileCore(transaction, fsei.LongFullPath, true, PathFormat.LongFullPath);
else
File.DeleteFileCore(transaction, fsei.LongFullPath, true, PathFormat.LongFullPath);
}
}
}


if (cmr.IsCanceled)
return cmr;
if (cmr.IsCanceled)
return cmr;
}
}


// Remove source folder.
if (emulateMove && cmr.ErrorCode == Win32Errors.ERROR_SUCCESS)
DeleteDirectoryCore(null, transaction, sourcePathLp, true, true, false, true, PathFormat.LongFullPath);
DeleteDirectoryCore(null, transaction, sourcePathLp, true, true, true, PathFormat.LongFullPath);
}

#endregion // Copy
@@ -950,7 +959,7 @@ namespace Alphaleonis.Win32.Filesystem
{
// MoveOptions.ReplaceExisting: This value cannot be used if lpNewFileName or lpExistingFileName names a directory.
if (((MoveOptions) moveOptions & MoveOptions.ReplaceExisting) != 0)
DeleteDirectoryCore(null, transaction, destinationPathLp, true, true, false, true, PathFormat.LongFullPath);
DeleteDirectoryCore(null, transaction, destinationPathLp, true, true, true, PathFormat.LongFullPath);


// Moves a file or directory, including its children.
@@ -961,7 +970,7 @@ namespace Alphaleonis.Win32.Filesystem
#endregion // Move


return cmr;
return isMove ? null : cmr;
}

#endregion // Internal Methods


+ 71
- 66
AlphaFS/Filesystem/Directory Class/Directory.Delete.cs 查看文件

@@ -20,6 +20,7 @@
*/

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
@@ -44,7 +45,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static void Delete(string path)
{
DeleteDirectoryCore(null, null, path, false, false, true, false, PathFormat.RelativePath);
DeleteDirectoryCore(null, null, path, false, false, false, PathFormat.RelativePath);
}

/// <summary>Deletes the specified directory and, if indicated, any subdirectories in the directory.</summary>
@@ -60,7 +61,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static void Delete(string path, bool recursive)
{
DeleteDirectoryCore(null, null, path, recursive, false, !recursive, false, PathFormat.RelativePath);
DeleteDirectoryCore(null, null, path, recursive, false, false, PathFormat.RelativePath);
}

#endregion // .NET
@@ -78,11 +79,10 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static void Delete(string path, PathFormat pathFormat)
{
DeleteDirectoryCore(null, null, path, false, false, true, false, pathFormat);
DeleteDirectoryCore(null, null, path, false, false, false, pathFormat);
}



/// <summary>[AlphaFS] Deletes the specified directory and, if indicated, any subdirectories in the directory.</summary>
/// <exception cref="ArgumentException"/>
/// <exception cref="ArgumentNullException"/>
@@ -97,11 +97,10 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static void Delete(string path, bool recursive, PathFormat pathFormat)
{
DeleteDirectoryCore(null, null, path, recursive, false, !recursive, false, pathFormat);
DeleteDirectoryCore(null, null, path, recursive, false, false, pathFormat);
}



/// <summary>[AlphaFS] Deletes the specified directory and, if indicated, any subdirectories in the directory.</summary>
/// <exception cref="ArgumentException"/>
/// <exception cref="ArgumentNullException"/>
@@ -116,7 +115,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static void Delete(string path, bool recursive, bool ignoreReadOnly)
{
DeleteDirectoryCore(null, null, path, recursive, ignoreReadOnly, !recursive, false, PathFormat.RelativePath);
DeleteDirectoryCore(null, null, path, recursive, ignoreReadOnly, false, PathFormat.RelativePath);
}

/// <summary>[AlphaFS] Deletes the specified directory and, if indicated, any subdirectories in the directory.</summary>
@@ -134,9 +133,10 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static void Delete(string path, bool recursive, bool ignoreReadOnly, PathFormat pathFormat)
{
DeleteDirectoryCore(null, null, path, recursive, ignoreReadOnly, !recursive, false, pathFormat);
DeleteDirectoryCore(null, null, path, recursive, ignoreReadOnly, false, pathFormat);
}


#region Transactional

/// <summary>[AlphaFS] Deletes an empty directory from a specified path.</summary>
@@ -152,7 +152,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static void DeleteTransacted(KernelTransaction transaction, string path)
{
DeleteDirectoryCore(null, transaction, path, false, false, true, false, PathFormat.RelativePath);
DeleteDirectoryCore(null, transaction, path, false, false, false, PathFormat.RelativePath);
}

/// <summary>[AlphaFS] Deletes an empty directory from a specified path.</summary>
@@ -169,11 +169,10 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static void DeleteTransacted(KernelTransaction transaction, string path, PathFormat pathFormat)
{
DeleteDirectoryCore(null, transaction, path, false, false, true, false, pathFormat);
DeleteDirectoryCore(null, transaction, path, false, false, false, pathFormat);
}



/// <summary>[AlphaFS] Deletes the specified directory and, if indicated, any subdirectories in the directory.</summary>
/// <exception cref="ArgumentException"/>
/// <exception cref="ArgumentNullException"/>
@@ -188,7 +187,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static void DeleteTransacted(KernelTransaction transaction, string path, bool recursive)
{
DeleteDirectoryCore(null, transaction, path, recursive, false, !recursive, false, PathFormat.RelativePath);
DeleteDirectoryCore(null, transaction, path, recursive, false, false, PathFormat.RelativePath);
}

/// <summary>[AlphaFS] Deletes the specified directory and, if indicated, any subdirectories in the directory.</summary>
@@ -206,10 +205,9 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static void DeleteTransacted(KernelTransaction transaction, string path, bool recursive, PathFormat pathFormat)
{
DeleteDirectoryCore(null, transaction, path, recursive, false, !recursive, false, pathFormat);
DeleteDirectoryCore(null, transaction, path, recursive, false, false, pathFormat);
}



/// <summary>[AlphaFS] Deletes the specified directory and, if indicated, any subdirectories in the directory.</summary>
/// <exception cref="ArgumentException"/>
@@ -226,7 +224,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static void DeleteTransacted(KernelTransaction transaction, string path, bool recursive, bool ignoreReadOnly)
{
DeleteDirectoryCore(null, transaction, path, recursive, ignoreReadOnly, !recursive, false, PathFormat.RelativePath);
DeleteDirectoryCore(null, transaction, path, recursive, ignoreReadOnly, false, PathFormat.RelativePath);
}

/// <summary>[AlphaFS] Deletes the specified directory and, if indicated, any subdirectories in the directory.</summary>
@@ -245,11 +243,12 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static void DeleteTransacted(KernelTransaction transaction, string path, bool recursive, bool ignoreReadOnly, PathFormat pathFormat)
{
DeleteDirectoryCore(null, transaction, path, recursive, ignoreReadOnly, !recursive, false, pathFormat);
DeleteDirectoryCore(null, transaction, path, recursive, ignoreReadOnly, false, pathFormat);
}

#endregion // Transactional


#region Internal Methods

/// <summary>Deletes the specified directory and, if indicated, any subdirectories in the directory.</summary>
@@ -261,76 +260,81 @@ namespace Alphaleonis.Win32.Filesystem
/// <exception cref="NotSupportedException"/>
/// <exception cref="UnauthorizedAccessException"/>
/// <exception cref="DirectoryReadOnlyException"/>
/// <param name="fileSystemEntryInfo">A FileSystemEntryInfo instance. Use either <paramref name="fileSystemEntryInfo"/> or <paramref name="path"/>, not both.</param>
/// <param name="fsEntryInfo">A FileSystemEntryInfo instance. Use either <paramref name="fsEntryInfo"/> or <paramref name="path"/>, not both.</param>
/// <param name="transaction">The transaction.</param>
/// <param name="path">The name of the directory to remove. Use either <paramref name="path"/> or <paramref name="fileSystemEntryInfo"/>, not both.</param>
/// <param name="path">The name of the directory to remove. Use either <paramref name="path"/> or <paramref name="fsEntryInfo"/>, not both.</param>
/// <param name="recursive"><see langword="true"/> to remove all files and subdirectories recursively; <see langword="false"/> otherwise only the top level empty directory.</param>
/// <param name="ignoreReadOnly"><see langword="true"/> overrides read only attribute of files and directories.</param>
/// <param name="requireEmpty"><see langword="true"/> requires the directory must be empty.</param>
/// <param name="continueOnNotExist"><see langword="true"/> does not throw an Exception when the file system object does not exist.</param>
/// <param name="continueOnNotFound">When <see langword="true"/> does not throw an Exception when the directory does not exist.</param>
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
[SecurityCritical]
internal static void DeleteDirectoryCore(FileSystemEntryInfo fileSystemEntryInfo, KernelTransaction transaction, string path, bool recursive, bool ignoreReadOnly, bool requireEmpty, bool continueOnNotExist, PathFormat pathFormat)
internal static void DeleteDirectoryCore(FileSystemEntryInfo fsEntryInfo, KernelTransaction transaction, string path, bool recursive, bool ignoreReadOnly, bool continueOnNotFound, PathFormat pathFormat)
{
#region Setup

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

if (fileSystemEntryInfo == null)
if (fsEntryInfo == 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 (pathFormat == PathFormat.RelativePath)
Path.CheckSupportedPathFormat(path, true, true);

if (fileSystemEntryInfo == null)
return;
fsEntryInfo = File.GetFileSystemEntryInfoCore(true, transaction, Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator), continueOnNotFound, pathFormat);

string pathLp = fileSystemEntryInfo.LongFullPath;
if (fsEntryInfo == null)
return;
}

#endregion // Setup

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

// 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)
if (recursive && !fsEntryInfo.IsReparsePoint)
{
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.
}

var dirs = new Stack<string>(1000);

if (recursive)
{
// Enumerate all file system objects.
foreach (var fsei in EnumerateFileSystemEntryInfosCore<FileSystemEntryInfo>(transaction, pathLp, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.LongFullPath))
foreach (var fsei in EnumerateFileSystemEntryInfosCore<FileSystemEntryInfo>(transaction, fsEntryInfo.LongFullPath, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders | DirectoryEnumerationOptions.Recursive, PathFormat.LongFullPath))
{
if (fsei.IsDirectory)
DeleteDirectoryCore(fsei, transaction, null, true, ignoreReadOnly, requireEmpty, true, PathFormat.LongFullPath);
{
// Check to see if this is a mount point, and unmount it.
// Now it is safe to delete the actual directory.
if (fsei.IsMountPoint)
Volume.DeleteVolumeMountPointCore(fsei.LongFullPath, false);

dirs.Push(fsei.LongFullPath);
}

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


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

#region Remove

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

DeleteDirectoryCore(transaction, fsEntryInfo.LongFullPath, ignoreReadOnly, continueOnNotFound);
}

private static void DeleteDirectoryCore(KernelTransaction transaction, string pathLp, bool ignoreReadOnly, bool continueOnNotFound)
{
startRemoveDirectory:

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

// RemoveDirectory() / RemoveDirectoryTransacted()
// In the ANSI version of this function, the name is limited to MAX_PATH characters.
@@ -340,17 +344,17 @@ namespace Alphaleonis.Win32.Filesystem
// RemoveDirectory on a symbolic link will remove the link itself.

? NativeMethods.RemoveDirectory(pathLp)
: NativeMethods.RemoveDirectoryTransacted(pathLp, transaction.SafeHandle)))
: NativeMethods.RemoveDirectoryTransacted(pathLp, transaction.SafeHandle);


var lastError = Marshal.GetLastWin32Error();
if (!success)
{
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;
// MSDN: .NET 3.5+: IOException: The directory specified by path is not an empty directory.
throw new DirectoryNotEmptyException(pathLp);


case Win32Errors.ERROR_DIRECTORY:
@@ -361,18 +365,20 @@ namespace Alphaleonis.Win32.Filesystem


case Win32Errors.ERROR_PATH_NOT_FOUND:
if (continueOnNotExist)
if (continueOnNotFound)
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);
var dataInitialised = File.FillAttributeInfoCore(transaction, pathLp, ref data, false, true);

if (data.dwFileAttributes != (FileAttributes) (-1))
{
@@ -383,7 +389,7 @@ namespace Alphaleonis.Win32.Filesystem
if (ignoreReadOnly)
{
// Reset directory attributes.
File.SetAttributesCore(true, transaction, pathLp, FileAttributes.Normal, true, PathFormat.LongFullPath);
File.SetAttributesCore(true, transaction, pathLp, FileAttributes.Normal, PathFormat.LongFullPath);
goto startRemoveDirectory;
}

@@ -392,8 +398,9 @@ namespace Alphaleonis.Win32.Filesystem
}
}


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

break;
@@ -408,8 +415,6 @@ namespace Alphaleonis.Win32.Filesystem

NativeError.ThrowException(lastError, pathLp);
}

#endregion // Remove
}

#endregion // Internal Methods


+ 165
- 43
AlphaFS/Filesystem/Directory Class/Directory.DeleteEmptySubdirectories.cs 查看文件

@@ -20,6 +20,7 @@
*/

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -32,47 +33,76 @@ namespace Alphaleonis.Win32.Filesystem
/// <summary>[AlphaFS] Deletes empty subdirectories from the specified directory.</summary>
/// <exception cref="ArgumentException"/>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="DirectoryNotFoundException"/>
/// <exception cref="IOException"/>
/// <exception cref="NotSupportedException"/>
/// <exception cref="UnauthorizedAccessException"/>
/// <exception cref="DirectoryReadOnlyException"/>
/// <param name="path">The name of the directory to remove empty subdirectories from.</param>
[SecurityCritical]
public static void DeleteEmptySubdirectories(string path)
{
DeleteEmptySubdirectoriesCore(null, null, path, false, false, PathFormat.RelativePath);
}

/// <summary>[AlphaFS] Deletes empty subdirectories from the specified directory.</summary>
/// <exception cref="ArgumentException"/>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="DirectoryNotFoundException"/>
/// <exception cref="IOException"/>
/// <exception cref="NotSupportedException"/>
/// <exception cref="UnauthorizedAccessException"/>
/// <exception cref="DirectoryReadOnlyException"/>
/// <param name="path">The name of the directory to remove empty subdirectories from.</param>
/// <param name="recursive"><see langword="true"/> deletes empty subdirectories from this directory and its subdirectories.</param>
[SecurityCritical]
public static void DeleteEmptySubdirectories(string path, bool recursive)
{
DeleteEmptySubdirectoriesCore(null, null, path, recursive, false, true, PathFormat.RelativePath);
DeleteEmptySubdirectoriesCore(null, null, path, recursive, false, PathFormat.RelativePath);
}

/// <summary>[AlphaFS] Deletes empty subdirectories from the specified directory.</summary>
/// <exception cref="ArgumentException"/>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="DirectoryNotFoundException"/>
/// <exception cref="IOException"/>
/// <exception cref="NotSupportedException"/>
/// <exception cref="UnauthorizedAccessException"/>
/// <exception cref="DirectoryReadOnlyException"/>
/// <param name="path">The name of the directory to remove empty subdirectories from.</param>
/// <param name="recursive"><see langword="true"/> deletes empty subdirectories from this directory and its subdirectories.</param>
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
[SecurityCritical]
public static void DeleteEmptySubdirectories(string path, bool recursive, PathFormat pathFormat)
{
DeleteEmptySubdirectoriesCore(null, null, path, recursive, false, true, pathFormat);
DeleteEmptySubdirectoriesCore(null, null, path, recursive, false, pathFormat);
}



/// <summary>[AlphaFS] Deletes empty subdirectories from the specified directory.</summary>
/// <exception cref="ArgumentException"/>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="DirectoryNotFoundException"/>
/// <exception cref="IOException"/>
/// <exception cref="NotSupportedException"/>
/// <exception cref="UnauthorizedAccessException"/>
/// <exception cref="DirectoryReadOnlyException"/>
/// <param name="path">The name of the directory to remove empty subdirectories from.</param>
/// <param name="recursive"><see langword="true"/> deletes empty subdirectories from this directory and its subdirectories.</param>
/// <param name="ignoreReadOnly"><see langword="true"/> overrides read only <see cref="FileAttributes"/> of empty directories.</param>
[SecurityCritical]
public static void DeleteEmptySubdirectories(string path, bool recursive, bool ignoreReadOnly)
{
DeleteEmptySubdirectoriesCore(null, null, path, recursive, ignoreReadOnly, true, PathFormat.RelativePath);
DeleteEmptySubdirectoriesCore(null, null, path, recursive, ignoreReadOnly, PathFormat.RelativePath);
}

/// <summary>[AlphaFS] Deletes empty subdirectories from the specified directory.</summary>
/// <exception cref="ArgumentException"/>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="DirectoryNotFoundException"/>
/// <exception cref="IOException"/>
/// <exception cref="NotSupportedException"/>
/// <exception cref="UnauthorizedAccessException"/>
/// <exception cref="DirectoryReadOnlyException"/>
/// <param name="path">The name of the directory to remove empty subdirectories from.</param>
/// <param name="recursive"><see langword="true"/> deletes empty subdirectories from this directory and its subdirectories.</param>
/// <param name="ignoreReadOnly"><see langword="true"/> overrides read only <see cref="FileAttributes"/> of empty directories.</param>
@@ -80,28 +110,53 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static void DeleteEmptySubdirectories(string path, bool recursive, bool ignoreReadOnly, PathFormat pathFormat)
{
DeleteEmptySubdirectoriesCore(null, null, path, recursive, ignoreReadOnly, true, pathFormat);
DeleteEmptySubdirectoriesCore(null, null, path, recursive, ignoreReadOnly, pathFormat);
}


#region Transactional

/// <summary>[AlphaFS] Deletes empty subdirectories from the specified directory.</summary>
/// <exception cref="ArgumentException"/>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="DirectoryNotFoundException"/>
/// <exception cref="IOException"/>
/// <exception cref="NotSupportedException"/>
/// <exception cref="UnauthorizedAccessException"/>
/// <exception cref="DirectoryReadOnlyException"/>
/// <param name="transaction">The transaction.</param>
/// <param name="path">The name of the directory to remove empty subdirectories from.</param>
[SecurityCritical]
public static void DeleteEmptySubdirectoriesTransacted(KernelTransaction transaction, string path)
{
DeleteEmptySubdirectoriesCore(null, transaction, path, false, false, PathFormat.RelativePath);
}

/// <summary>[AlphaFS] Deletes empty subdirectories from the specified directory.</summary>
/// <exception cref="ArgumentException"/>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="DirectoryNotFoundException"/>
/// <exception cref="IOException"/>
/// <exception cref="NotSupportedException"/>
/// <exception cref="UnauthorizedAccessException"/>
/// <exception cref="DirectoryReadOnlyException"/>
/// <param name="transaction">The transaction.</param>
/// <param name="path">The name of the directory to remove empty subdirectories from.</param>
/// <param name="recursive"><see langword="true"/> deletes empty subdirectories from this directory and its subdirectories.</param>
[SecurityCritical]
public static void DeleteEmptySubdirectoriesTransacted(KernelTransaction transaction, string path, bool recursive)
{
DeleteEmptySubdirectoriesCore(null, transaction, path, recursive, false, true, PathFormat.RelativePath);
DeleteEmptySubdirectoriesCore(null, transaction, path, recursive, false, PathFormat.RelativePath);
}

/// <summary>[AlphaFS] Deletes empty subdirectories from the specified directory.</summary>
/// <exception cref="ArgumentException"/>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="DirectoryNotFoundException"/>
/// <exception cref="IOException"/>
/// <exception cref="NotSupportedException"/>
/// <exception cref="UnauthorizedAccessException"/>
/// <exception cref="DirectoryReadOnlyException"/>
/// <param name="transaction">The transaction.</param>
/// <param name="path">The name of the directory to remove empty subdirectories from.</param>
/// <param name="recursive"><see langword="true"/> deletes empty subdirectories from this directory and its subdirectories.</param>
@@ -109,15 +164,17 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static void DeleteEmptySubdirectoriesTransacted(KernelTransaction transaction, string path, bool recursive, PathFormat pathFormat)
{
DeleteEmptySubdirectoriesCore(null, transaction, path, recursive, false, true, pathFormat);
DeleteEmptySubdirectoriesCore(null, transaction, path, recursive, false, pathFormat);
}



/// <summary>[AlphaFS] Deletes empty subdirectories from the specified directory.</summary>
/// <exception cref="ArgumentException"/>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="DirectoryNotFoundException"/>
/// <exception cref="IOException"/>
/// <exception cref="NotSupportedException"/>
/// <exception cref="UnauthorizedAccessException"/>
/// <exception cref="DirectoryReadOnlyException"/>
/// <param name="transaction">The transaction.</param>
/// <param name="path">The name of the directory to remove empty subdirectories from.</param>
/// <param name="recursive"><see langword="true"/> deletes empty subdirectories from this directory and its subdirectories.</param>
@@ -125,13 +182,17 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static void DeleteEmptySubdirectoriesTransacted(KernelTransaction transaction, string path, bool recursive, bool ignoreReadOnly)
{
DeleteEmptySubdirectoriesCore(null, transaction, path, recursive, ignoreReadOnly, true, PathFormat.RelativePath);
DeleteEmptySubdirectoriesCore(null, transaction, path, recursive, ignoreReadOnly, PathFormat.RelativePath);
}

/// <summary>[AlphaFS] Deletes empty subdirectories from the specified directory.</summary>
/// <exception cref="ArgumentException"/>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="DirectoryNotFoundException"/>
/// <exception cref="IOException"/>
/// <exception cref="NotSupportedException"/>
/// <exception cref="UnauthorizedAccessException"/>
/// <exception cref="DirectoryReadOnlyException"/>
/// <param name="transaction">The transaction.</param>
/// <param name="path">The name of the directory to remove empty subdirectories from.</param>
/// <param name="recursive"><see langword="true"/> deletes empty subdirectories from this directory and its subdirectories.</param>
@@ -140,69 +201,130 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static void DeleteEmptySubdirectoriesTransacted(KernelTransaction transaction, string path, bool recursive, bool ignoreReadOnly, PathFormat pathFormat)
{
DeleteEmptySubdirectoriesCore(null, transaction, path, recursive, ignoreReadOnly, true, pathFormat);
DeleteEmptySubdirectoriesCore(null, transaction, path, recursive, ignoreReadOnly, pathFormat);
}

#endregion // Transactional


#region Internal Methods

/// <summary>Delete empty subdirectories from the specified directory.</summary>
/// <summary>[AlphaFS] Delete empty subdirectories from the specified directory.</summary>
/// <exception cref="ArgumentException"/>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="DirectoryNotFoundException"/>
/// <exception cref="IOException"/>
/// <exception cref="NotSupportedException"/>
/// <exception cref="UnauthorizedAccessException"/>
/// <param name="fileSystemEntryInfo">A FileSystemEntryInfo instance. Use either <paramref name="fileSystemEntryInfo"/> or <paramref name="path"/>, not both.</param>
/// <exception cref="DirectoryReadOnlyException"/>
/// <param name="fsEntryInfo">A FileSystemEntryInfo instance. Use either <paramref name="fsEntryInfo"/> or <paramref name="path"/>, not both.</param>
/// <param name="transaction">The transaction.</param>
/// <param name="path">The name of the directory to remove empty subdirectories from. Use either <paramref name="path"/> or <paramref name="fileSystemEntryInfo"/>, not both.</param>
/// <param name="path">The name of the directory to remove empty subdirectories from. Use either <paramref name="path"/> or <paramref name="fsEntryInfo"/>, not both.</param>
/// <param name="recursive"><see langword="true"/> deletes empty subdirectories from this directory and its subdirectories.</param>
/// <param name="ignoreReadOnly"><see langword="true"/> overrides read only <see cref="FileAttributes"/> of empty directories.</param>
/// <param name="initialize">When <see langword="true"/> indicates the method is called externally.</param>
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
[SecurityCritical]
internal static void DeleteEmptySubdirectoriesCore(FileSystemEntryInfo fileSystemEntryInfo, KernelTransaction transaction, string path, bool recursive, bool ignoreReadOnly, bool initialize, PathFormat pathFormat)
internal static void DeleteEmptySubdirectoriesCore0(FileSystemEntryInfo fsEntryInfo, 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 (fsEntryInfo == null)
{
if (pathFormat == PathFormat.RelativePath)
Path.CheckSupportedPathFormat(path, true, true);

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;
fsEntryInfo = File.GetFileSystemEntryInfoCore(true, transaction, Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck) , false, pathFormat);

if (fsEntryInfo == null)
return;
}
#endregion // Setup


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

var dirEnumOptions = DirectoryEnumerationOptions.Folders;
var dirEnumOptions = DirectoryEnumerationOptions.Folders | DirectoryEnumerationOptions.SkipReparsePoints;

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);

foreach (var fsei in EnumerateFileSystemEntryInfosCore<FileSystemEntryInfo>(transaction, fsEntryInfo.LongFullPath, Path.WildcardStarMatchAll, dirEnumOptions, PathFormat.LongFullPath))
DeleteEmptySubdirectoriesCore0(fsei, transaction, null, recursive, ignoreReadOnly, false, PathFormat.LongFullPath);


if (!EnumerateFileSystemEntryInfosCore<string>(transaction, pathLp, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.LongFullPath).Any())
if (!EnumerateFileSystemEntryInfosCore<string>(transaction, fsEntryInfo.LongFullPath, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.LongFullPath).Any())
{
// Prevent deleting path itself.
if (!initialize)
DeleteDirectoryCore(fileSystemEntryInfo, transaction, null, false, ignoreReadOnly, true, true, PathFormat.LongFullPath);
DeleteDirectoryCore(fsEntryInfo, transaction, null, false, ignoreReadOnly, true, PathFormat.LongFullPath);
}
}


/// <summary>[AlphaFS] Delete empty subdirectories from the specified directory.</summary>
/// <exception cref="ArgumentException"/>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="DirectoryNotFoundException"/>
/// <exception cref="IOException"/>
/// <exception cref="NotSupportedException"/>
/// <exception cref="UnauthorizedAccessException"/>
/// <exception cref="DirectoryReadOnlyException"/>
/// <param name="fsEntryInfo">A FileSystemEntryInfo instance. Use either <paramref name="fsEntryInfo"/> or <paramref name="path"/>, not both.</param>
/// <param name="transaction">The transaction.</param>
/// <param name="path">The name of the directory to remove empty subdirectories from. Use either <paramref name="path"/> or <paramref name="fsEntryInfo"/>, not both.</param>
/// <param name="recursive"><see langword="true"/> deletes empty subdirectories from this directory and its subdirectories.</param>
/// <param name="ignoreReadOnly"><see langword="true"/> overrides read only <see cref="FileAttributes"/> of empty directories.</param>
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
[SecurityCritical]
internal static void DeleteEmptySubdirectoriesCore(FileSystemEntryInfo fsEntryInfo, KernelTransaction transaction, string path, bool recursive, bool ignoreReadOnly, PathFormat pathFormat)
{
#region Setup

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

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

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

if (fsEntryInfo == null)
return;
}

#endregion // Setup


// Ensure path is a directory.
if (!fsEntryInfo.IsDirectory)
throw new IOException(string.Format(CultureInfo.CurrentCulture, 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>(transaction, dirs.Pop(), Path.WildcardStarMatchAll, DirectoryEnumerationOptions.Folders | DirectoryEnumerationOptions.ContinueOnException, PathFormat.LongFullPath))
{
// Ensure the directory is empty.
if (!EnumerateFileSystemEntryInfosCore<string>(transaction, fsei.LongFullPath, Path.WildcardStarMatchAll, DirectoryEnumerationOptions.FilesAndFolders, PathFormat.LongFullPath).Any())
DeleteDirectoryCore(fsei, transaction, null, false, ignoreReadOnly, true, PathFormat.LongFullPath);

else if (recursive)
dirs.Push(fsei.LongFullPath);
}
}
}



+ 5
- 1
AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.CreateSubdirectory.cs 查看文件

@@ -20,6 +20,7 @@
*/

using System;
using System.Diagnostics.CodeAnalysis;
using System.Security;
using System.Security.AccessControl;

@@ -54,6 +55,7 @@ namespace Alphaleonis.Win32.Filesystem
/// If the subdirectory already exists, this method does nothing.
/// </remarks>

[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
[SecurityCritical]
public DirectoryInfo CreateSubdirectory(string path, DirectorySecurity directorySecurity)
{
@@ -108,6 +110,7 @@ namespace Alphaleonis.Win32.Filesystem
/// If the subdirectory already exists, this method does nothing.
/// </remarks>

[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
[SecurityCritical]
public DirectoryInfo CreateSubdirectory(string path, DirectorySecurity directorySecurity, bool compress)
{
@@ -126,6 +129,7 @@ namespace Alphaleonis.Win32.Filesystem
/// If the subdirectory already exists, this method does nothing.
/// </remarks>

[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")]
[SecurityCritical]
public DirectoryInfo CreateSubdirectory(string path, string templatePath, DirectorySecurity directorySecurity, bool compress)
{
@@ -148,7 +152,7 @@ namespace Alphaleonis.Win32.Filesystem
/// <param name="directorySecurity">The <see cref="DirectorySecurity"/> security to apply.</param>
/// <param name="compress">When <see langword="true"/> compresses the directory.</param>
[SecurityCritical]
private DirectoryInfo CreateSubdirectoryCore(string path, string templatePath, DirectorySecurity directorySecurity, bool compress)
private DirectoryInfo CreateSubdirectoryCore(string path, string templatePath, ObjectSecurity directorySecurity, bool compress)
{
string pathLp = Path.CombineCore(false, LongFullName, path);
string templatePathLp = templatePath == null ? null :


+ 3
- 3
AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.Delete.cs 查看文件

@@ -39,7 +39,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public override void Delete()
{
Directory.DeleteDirectoryCore(null, Transaction, LongFullName, false, false, true, false, PathFormat.LongFullPath);
Directory.DeleteDirectoryCore(EntryInfo, Transaction, null, false, false, false, PathFormat.LongFullPath);
}

/// <summary>Deletes this instance of a <see cref="DirectoryInfo"/>, specifying whether to delete subdirectories and files.</summary>
@@ -57,7 +57,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public void Delete(bool recursive)
{
Directory.DeleteDirectoryCore(null, Transaction, LongFullName, recursive, false, !recursive, false, PathFormat.LongFullPath);
Directory.DeleteDirectoryCore(EntryInfo, Transaction, null, recursive, false, false, PathFormat.LongFullPath);
}

#endregion // .NET
@@ -80,7 +80,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public void Delete(bool recursive, bool ignoreReadOnly)
{
Directory.DeleteDirectoryCore(null, Transaction, LongFullName, recursive, ignoreReadOnly, !recursive, false, PathFormat.LongFullPath);
Directory.DeleteDirectoryCore(EntryInfo, Transaction, null, recursive, ignoreReadOnly, false, PathFormat.LongFullPath);
}

#endregion // AlphaFS


+ 3
- 3
AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.DeleteEmptySubdirectories.cs 查看文件

@@ -32,7 +32,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public void DeleteEmptySubdirectories()
{
Directory.DeleteEmptySubdirectoriesCore(null, Transaction, LongFullName, false, false, true, PathFormat.LongFullPath);
Directory.DeleteEmptySubdirectoriesCore(EntryInfo, Transaction, null, false, false, PathFormat.LongFullPath);
}

/// <summary>[AlphaFS] Deletes empty subdirectories from the <see cref="DirectoryInfo"/> instance.</summary>
@@ -40,7 +40,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public void DeleteEmptySubdirectories(bool recursive)
{
Directory.DeleteEmptySubdirectoriesCore(null, Transaction, LongFullName, recursive, false, true, PathFormat.LongFullPath);
Directory.DeleteEmptySubdirectoriesCore(EntryInfo, Transaction, null, recursive, false, PathFormat.LongFullPath);
}

/// <summary>[AlphaFS] Deletes empty subdirectories from the <see cref="DirectoryInfo"/> instance.</summary>
@@ -49,7 +49,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public void DeleteEmptySubdirectories(bool recursive, bool ignoreReadOnly)
{
Directory.DeleteEmptySubdirectoriesCore(null, Transaction, LongFullName, recursive, ignoreReadOnly, true, PathFormat.LongFullPath);
Directory.DeleteEmptySubdirectoriesCore(EntryInfo, Transaction, null, recursive, ignoreReadOnly, PathFormat.LongFullPath);
}

#endregion // AlphaFS


+ 4
- 4
AlphaFS/Filesystem/Enumerations/CopyMoveProgressResult.cs 查看文件

@@ -25,22 +25,22 @@ namespace Alphaleonis.Win32.Filesystem
public enum CopyMoveProgressResult
{
/// <summary>PROGRESS_CONTINUE
/// <para>Continue the copy operation.</para>
/// <para>Continue the copy/move operation.</para>
/// </summary>
Continue = 0,

/// <summary>PROGRESS_CANCEL
/// <para>Cancel the copy operation and delete the destination file.</para>
/// <para>Cancel the copy/move operation and delete the destination file.</para>
/// </summary>
Cancel = 1,

/// <summary>PROGRESS_STOP
/// <para>Stop the copy operation. It can be restarted at a later time.</para>
/// <para>Stop the copy/move operation. It can be restarted at a later time.</para>
/// </summary>
Stop = 2,

/// <summary>PROGRESS_QUIET
/// <para>Continue the copy operation, but stop invoking <see cref="CopyMoveProgressRoutine"/> to report progress.</para>
/// <para>Continue the copy/move operation, but stop invoking <see cref="CopyMoveProgressRoutine"/> to report progress.</para>
/// </summary>
Quiet = 3
}

+ 1
- 1
AlphaFS/Filesystem/Enumerations/DiGetClassFlags.cs 查看文件

@@ -55,7 +55,7 @@ namespace Alphaleonis.Win32.Filesystem
/// This flag must be set in the Flags parameter if the Enumerator parameter specifies a Device Instance ID.
/// </para>
/// </summary>
DeviceInterface = 16,
DeviceInterface = 16
}
}
}

+ 1
- 1
AlphaFS/Filesystem/Enumerations/DosDeviceAttributes.cs 查看文件

@@ -55,6 +55,6 @@ namespace Alphaleonis.Win32.Filesystem
/// <para>Do not broadcast the WM_SETTINGCHANGE message.</para>
/// <para>By default, this message is broadcast to notify the shell and applications of the change.</para>
/// </summary>
NoBroadcastSystem = 8,
NoBroadcastSystem = 8
}
}

+ 1
- 1
AlphaFS/Filesystem/Enumerations/ExtendedFileAttributes.cs 查看文件

@@ -26,7 +26,7 @@ using System.IO;
namespace Alphaleonis.Win32.Filesystem
{
/// <summary>Specifies how the operating system should open a file.</summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2217:DoNotMarkEnumsWithFlags")]
[SuppressMessage("Microsoft.Usage", "CA2217:DoNotMarkEnumsWithFlags")]
[Flags]
public enum ExtendedFileAttributes
{


+ 1
- 1
AlphaFS/Filesystem/Enumerations/FileInfoByHandleClass.cs 查看文件

@@ -138,7 +138,7 @@ namespace Alphaleonis.Win32.Filesystem
/// <para>will resume the enumeration operation after the last file is returned.</para>
/// </remarks>
/// </summary>
FileIdBothDirectoryInfo = 10,
FileIdBothDirectoryInfo = 10

#endregion // FILE_ID_BOTH_DIR_INFO



+ 1
- 1
AlphaFS/Filesystem/Enumerations/SymbolicLinkType.cs 查看文件

@@ -28,6 +28,6 @@ namespace Alphaleonis.Win32.Filesystem
Absolute = 0,

/// <summary>The symbolic link is relative.</summary>
Relative = 1,
Relative = 1
}
}

+ 3
- 6
AlphaFS/Filesystem/Exceptions/TransactionException.cs 查看文件

@@ -35,24 +35,21 @@ namespace Alphaleonis.Win32.Filesystem

/// <summary>Initializes a new instance of the <see cref="TransactionException"/> class.</summary>
/// <param name="message">The message.</param>
public TransactionException(string message)
: base(message)
public TransactionException(string message) : base(message)
{
}

/// <summary>Initializes a new instance of the <see cref="TransactionException"/> class.</summary>
/// <param name="message">The message.</param>
/// <param name="innerException">The inner exception.</param>
public TransactionException(string message, Exception innerException)
: base(message, innerException)
public TransactionException(string message, Exception innerException) : base(message, innerException)
{
}

/// <summary>Initializes a new instance of the <see cref="TransactionException"/> class.</summary>
/// <param name="info">The data for serializing or deserializing the object.</param>
/// <param name="context">The source and destination for the object.</param>
protected TransactionException(SerializationInfo info, StreamingContext context)
: base(info, context)
protected TransactionException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}

+ 36
- 44
AlphaFS/Filesystem/File Class/File.CopyMove.cs 查看文件

@@ -359,9 +359,9 @@ namespace Alphaleonis.Win32.Filesystem
/// <param name="progressHandler">A callback function that is called each time another portion of the file has been copied. This parameter can be <see langword="null"/>.</param>
/// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
[SecurityCritical]
public static CopyMoveResult Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData)
public static void Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData)
{
return CopyMoveCore(false, null, sourceFileName, destinationFileName, false, copyOptions, null, progressHandler, userProgressData, null, PathFormat.RelativePath);
CopyMoveCore(false, null, sourceFileName, destinationFileName, false, copyOptions, null, progressHandler, userProgressData, null, PathFormat.RelativePath);
}

/// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. <see cref="CopyOptions"/> can be specified,
@@ -388,9 +388,9 @@ namespace Alphaleonis.Win32.Filesystem
/// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
[SecurityCritical]
public static CopyMoveResult Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat)
public static void Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat)
{
return CopyMoveCore(false, null, sourceFileName, destinationFileName, false, copyOptions, null, progressHandler, userProgressData, null, pathFormat);
CopyMoveCore(false, null, sourceFileName, destinationFileName, false, copyOptions, null, progressHandler, userProgressData, null, pathFormat);
}

@@ -418,9 +418,9 @@ namespace Alphaleonis.Win32.Filesystem
/// <param name="progressHandler">A callback function that is called each time another portion of the file has been copied. This parameter can be <see langword="null"/>.</param>
/// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
[SecurityCritical]
public static CopyMoveResult Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates, CopyMoveProgressRoutine progressHandler, object userProgressData)
public static void Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates, CopyMoveProgressRoutine progressHandler, object userProgressData)
{
return CopyMoveCore(false, null, sourceFileName, destinationFileName, preserveDates, copyOptions, null, progressHandler, userProgressData, null, PathFormat.RelativePath);
CopyMoveCore(false, null, sourceFileName, destinationFileName, preserveDates, copyOptions, null, progressHandler, userProgressData, null, PathFormat.RelativePath);
}

/// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. <see cref="CopyOptions"/> can be specified,
@@ -448,9 +448,9 @@ namespace Alphaleonis.Win32.Filesystem
/// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
[SecurityCritical]
public static CopyMoveResult Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat)
public static void Copy(string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat)
{
return CopyMoveCore(false, null, sourceFileName, destinationFileName, preserveDates, copyOptions, null, progressHandler, userProgressData, null, pathFormat);
CopyMoveCore(false, null, sourceFileName, destinationFileName, preserveDates, copyOptions, null, progressHandler, userProgressData, null, pathFormat);
}

#endregion // Non-Transactional
@@ -584,9 +584,9 @@ namespace Alphaleonis.Win32.Filesystem
/// <param name="progressHandler">A callback function that is called each time another portion of the file has been copied. This parameter can be <see langword="null"/>.</param>
/// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
[SecurityCritical]
public static CopyMoveResult CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData)
public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData)
{
return CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, copyOptions, null, progressHandler, userProgressData, null, PathFormat.RelativePath);
CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, copyOptions, null, progressHandler, userProgressData, null, PathFormat.RelativePath);
}

/// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. <see cref="CopyOptions"/> can be specified,
@@ -614,9 +614,9 @@ namespace Alphaleonis.Win32.Filesystem
/// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
[SecurityCritical]
public static CopyMoveResult CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat)
public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat)
{
return CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, copyOptions, null, progressHandler, userProgressData, null, pathFormat);
CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, copyOptions, null, progressHandler, userProgressData, null, pathFormat);
}

@@ -645,9 +645,9 @@ namespace Alphaleonis.Win32.Filesystem
/// <param name="progressHandler">A callback function that is called each time another portion of the file has been copied. This parameter can be <see langword="null"/>.</param>
/// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
[SecurityCritical]
public static CopyMoveResult CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates, CopyMoveProgressRoutine progressHandler, object userProgressData)
public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates, CopyMoveProgressRoutine progressHandler, object userProgressData)
{
return CopyMoveCore(false, transaction, sourceFileName, destinationFileName, preserveDates, copyOptions, null, progressHandler, userProgressData, null, PathFormat.RelativePath);
CopyMoveCore(false, transaction, sourceFileName, destinationFileName, preserveDates, copyOptions, null, progressHandler, userProgressData, null, PathFormat.RelativePath);
}

/// <summary>[AlphaFS] Copies an existing file to a new file. Overwriting a file of the same name is allowed. <see cref="CopyOptions"/> can be specified,
@@ -676,9 +676,9 @@ namespace Alphaleonis.Win32.Filesystem
/// <exception cref="NotSupportedException"/>
/// <exception cref="UnauthorizedAccessException"/>
[SecurityCritical]
public static CopyMoveResult CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat)
public static void CopyTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, CopyOptions copyOptions, bool preserveDates, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat)
{
return CopyMoveCore(false, transaction, sourceFileName, destinationFileName, preserveDates, copyOptions, null, progressHandler, userProgressData, null, pathFormat);
CopyMoveCore(false, transaction, sourceFileName, destinationFileName, preserveDates, copyOptions, null, progressHandler, userProgressData, null, pathFormat);
}

#endregion // Transactional
@@ -880,9 +880,9 @@ namespace Alphaleonis.Win32.Filesystem
/// <param name="progressHandler">A callback function that is called each time another portion of the file has been moved. This parameter can be <see langword="null"/>.</param>
/// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
[SecurityCritical]
public static CopyMoveResult Move(string sourceFileName, string destinationFileName, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData)
public static void Move(string sourceFileName, string destinationFileName, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData)
{
return CopyMoveCore(false, null, sourceFileName, destinationFileName, false, null, moveOptions, progressHandler, userProgressData, null, PathFormat.RelativePath);
CopyMoveCore(false, null, sourceFileName, destinationFileName, false, null, moveOptions, progressHandler, userProgressData, null, PathFormat.RelativePath);
}

/// <summary>[AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name.</summary>
@@ -908,9 +908,9 @@ namespace Alphaleonis.Win32.Filesystem
/// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
[SecurityCritical]
public static CopyMoveResult Move(string sourceFileName, string destinationFileName, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat)
public static void Move(string sourceFileName, string destinationFileName, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat)
{
return CopyMoveCore(false, null, sourceFileName, destinationFileName, false, null, moveOptions, progressHandler, userProgressData, null, pathFormat);
CopyMoveCore(false, null, sourceFileName, destinationFileName, false, null, moveOptions, progressHandler, userProgressData, null, pathFormat);
}

#endregion // Non-Transactional
@@ -993,9 +993,9 @@ namespace Alphaleonis.Win32.Filesystem
/// <param name="progressHandler">A callback function that is called each time another portion of the file has been moved. This parameter can be <see langword="null"/>.</param>
/// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
[SecurityCritical]
public static CopyMoveResult MoveTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData)
public static void MoveTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData)
{
return CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, null, moveOptions, progressHandler, userProgressData, null, PathFormat.RelativePath);
CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, null, moveOptions, progressHandler, userProgressData, null, PathFormat.RelativePath);
}

/// <summary>[AlphaFS] Moves a specified file to a new location, providing the option to specify a new file name.</summary>
@@ -1022,9 +1022,9 @@ namespace Alphaleonis.Win32.Filesystem
/// <param name="userProgressData">The argument to be passed to the callback function. This parameter can be <see langword="null"/>.</param>
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
[SecurityCritical]
public static CopyMoveResult MoveTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat)
public static void MoveTransacted(KernelTransaction transaction, string sourceFileName, string destinationFileName, MoveOptions moveOptions, CopyMoveProgressRoutine progressHandler, object userProgressData, PathFormat pathFormat)
{
return CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, null, moveOptions, progressHandler, userProgressData, null, pathFormat);
CopyMoveCore(false, transaction, sourceFileName, destinationFileName, false, null, moveOptions, progressHandler, userProgressData, null, pathFormat);
}
#endregion // Transactional
@@ -1087,10 +1087,8 @@ namespace Alphaleonis.Win32.Filesystem

var sourceFileNameLp = sourceFileName;
var destFileNameLp = destinationFileName;
var skipPathChecks = pathFormat == PathFormat.LongFullPath;


if (!skipPathChecks)
if (pathFormat != PathFormat.LongFullPath)
{
Path.CheckSupportedPathFormat(sourceFileName, true, true);
Path.CheckSupportedPathFormat(destinationFileName, true, true);
@@ -1098,30 +1096,27 @@ namespace Alphaleonis.Win32.Filesystem
sourceFileNameLp = Path.GetExtendedLengthPathCore(transaction, sourceFileName, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator);
destFileNameLp = Path.GetExtendedLengthPathCore(transaction, destinationFileName, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator);
}


// MSDN: If this flag is set to TRUE during the copy/move operation, the operation is canceled.
// Otherwise, the copy/move operation will continue to completion.
var cancel = false;

// Determine Copy or Move action.
var isCopy = DetermineIsCopy(copyOptions, moveOptions);
var isMove = !isCopy;

var cmr = copyMoveResult ?? new CopyMoveResult(sourceFileName, destinationFileName, false, (int) Win32Errors.ERROR_SUCCESS);

var raiseException = progressHandler == null;
//Task completedTask = null;

// MSDN: If this flag is set to TRUE during the copy/move operation, the operation is canceled.
// Otherwise, the copy/move operation will continue to completion.
bool cancel;

var raiseException = progressHandler == null;

// Setup callback function for progress notifications.
var routine = progressHandler != null
var routine = !raiseException
? (totalFileSize, totalBytesTransferred, streamSize, streamBytesTransferred, dwStreamNumber, dwCallbackReason, hSourceFile, hDestinationFile, lpData) =>
progressHandler(totalFileSize, totalBytesTransferred, streamSize, streamBytesTransferred, dwStreamNumber, dwCallbackReason, userProgressData)
: (NativeMethods.NativeCopyMoveProgressRoutine) null;


var cmr = copyMoveResult ?? new CopyMoveResult(sourceFileNameLp, destFileNameLp, false, (int) Win32Errors.ERROR_SUCCESS);

#endregion // Setup


@@ -1153,8 +1148,6 @@ namespace Alphaleonis.Win32.Filesystem
: isMove
? NativeMethods.MoveFileTransacted(sourceFileNameLp, destFileNameLp, routine, IntPtr.Zero, (MoveOptions) moveOptions, transaction.SafeHandle)
: NativeMethods.CopyFileTransacted(sourceFileNameLp, destFileNameLp, routine, IntPtr.Zero, out cancel, (CopyOptions) copyOptions, transaction.SafeHandle);


var lastError = (uint) Marshal.GetLastWin32Error();
@@ -1174,8 +1167,7 @@ namespace Alphaleonis.Win32.Filesystem
// CopyFileEx will return zero and GetLastError will return ERROR_REQUEST_ABORTED.
// In this case, the partially copied destination file is left intact.

cancel = true;
cmr.IsCanceled = cancel;
cmr.IsCanceled = true;
}

else if (raiseException)
@@ -1267,7 +1259,7 @@ namespace Alphaleonis.Win32.Filesystem
if (((MoveOptions) moveOptions & MoveOptions.ReplaceExisting) != 0)
{
// Reset file system object attributes.
SetAttributesCore(isFolder, transaction, destFileNameLp, FileAttributes.Normal, true, PathFormat.LongFullPath);
SetAttributesCore(isFolder, transaction, destFileNameLp, FileAttributes.Normal, PathFormat.LongFullPath);

goto startCopyMove;
}


+ 1
- 1
AlphaFS/Filesystem/File Class/File.CreateHardlink.cs 查看文件

@@ -96,7 +96,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
internal static void CreateHardlinkCore(KernelTransaction transaction, string fileName, string existingFileName, PathFormat pathFormat)
{
var options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck;
const GetFullPathOptions options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck;

string fileNameLp = Path.GetExtendedLengthPathCore(transaction, fileName, pathFormat, options);
string existingFileNameLp = Path.GetExtendedLengthPathCore(transaction, existingFileName, pathFormat, options);


+ 1
- 1
AlphaFS/Filesystem/File Class/File.CreateSymbolicLink.cs 查看文件

@@ -110,7 +110,7 @@ namespace Alphaleonis.Win32.Filesystem
if (!NativeMethods.IsAtLeastWindowsVista)
throw new PlatformNotSupportedException(Resources.Requires_Windows_Vista_Or_Higher);

var options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck;
const GetFullPathOptions options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck;

string symlinkFileNameLp = Path.GetExtendedLengthPathCore(transaction, symlinkFileName, pathFormat, options);
string targetFileNameRp = Path.GetExtendedLengthPathCore(transaction, targetFileName, pathFormat, options);


+ 1
- 1
AlphaFS/Filesystem/File Class/File.Delete.cs 查看文件

@@ -209,7 +209,7 @@ namespace Alphaleonis.Win32.Filesystem
if (ignoreReadOnly)
{
// Reset file attributes.
SetAttributesCore(false, transaction, pathLp, FileAttributes.Normal, true, PathFormat.LongFullPath);
SetAttributesCore(false, transaction, pathLp, FileAttributes.Normal, PathFormat.LongFullPath);
goto startDeleteFile;
}



+ 1
- 1
AlphaFS/Filesystem/File Class/File.EncryptDecrypt.cs 查看文件

@@ -85,7 +85,7 @@ namespace Alphaleonis.Win32.Filesystem

// Reset file/directory attributes.
// MSDN: If lpFileName specifies a read-only file, the function fails and GetLastError returns ERROR_FILE_READ_ONLY.
SetAttributesCore(isFolder, null, pathLp, FileAttributes.Normal, true, PathFormat.LongFullPath);
SetAttributesCore(isFolder, null, pathLp, FileAttributes.Normal, PathFormat.LongFullPath);

// EncryptFile() / DecryptFile()
// In the ANSI version of this function, the name is limited to 248 characters.


+ 1
- 1
AlphaFS/Filesystem/File Class/File.GetHash.cs 查看文件

@@ -83,7 +83,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
internal static string GetHashCore(KernelTransaction transaction, string fileFullPath, HashType hashType, PathFormat pathFormat)
{
var options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck;
const GetFullPathOptions options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck;
var fileNameLp = Path.GetExtendedLengthPathCore(transaction, fileFullPath, pathFormat, options);

byte[] hash = null;


+ 1
- 1
AlphaFS/Filesystem/File Class/File.Replace.cs 查看文件

@@ -151,7 +151,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
internal static void ReplaceCore(string sourceFileName, string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors, PathFormat pathFormat)
{
var options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck;
const GetFullPathOptions options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck;

string sourceFileNameLp = Path.GetExtendedLengthPathCore(null, sourceFileName, pathFormat, options);
string destinationFileNameLp = Path.GetExtendedLengthPathCore(null, destinationFileName, pathFormat, options);


+ 12
- 16
AlphaFS/Filesystem/File Class/File.SetAttributes.cs 查看文件

@@ -44,7 +44,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static void SetAttributes(string path, FileAttributes fileAttributes)
{
SetAttributesCore(false, null, path, fileAttributes, false, PathFormat.RelativePath);
SetAttributesCore(false, null, path, fileAttributes, PathFormat.RelativePath);
}

/// <summary>[AlphaFS] Sets the specified <see cref="FileAttributes"/> of the file or directory on the specified path.</summary>
@@ -61,7 +61,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static void SetAttributes(string path, FileAttributes fileAttributes, PathFormat pathFormat)
{
SetAttributesCore(false, null, path, fileAttributes, false, pathFormat);
SetAttributesCore(false, null, path, fileAttributes, pathFormat);
}


@@ -81,7 +81,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static void SetAttributesTransacted(KernelTransaction transaction, string path, FileAttributes fileAttributes)
{
SetAttributesCore(false, transaction, path, fileAttributes, false, PathFormat.RelativePath);
SetAttributesCore(false, transaction, path, fileAttributes, PathFormat.RelativePath);
}

/// <summary>[AlphaFS] Sets the specified <see cref="FileAttributes"/> of the file on the specified path.</summary>
@@ -99,7 +99,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static void SetAttributesTransacted(KernelTransaction transaction, string path, FileAttributes fileAttributes, PathFormat pathFormat)
{
SetAttributesCore(false, transaction, path, fileAttributes, false, pathFormat);
SetAttributesCore(false, transaction, path, fileAttributes, pathFormat);
}

#endregion // Transacted
@@ -123,16 +123,13 @@ namespace Alphaleonis.Win32.Filesystem
/// <param name="fileAttributes">
/// The attributes to set for the file or directory. Note that all other values override <see cref="FileAttributes.Normal"/>.
/// </param>
/// <param name="continueOnNotExist">
/// <see langword="true"/> does not throw an Exception when the file system object does not exist.
/// </param>
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
[SecurityCritical]
internal static void SetAttributesCore(bool isFolder, KernelTransaction transaction, string path, FileAttributes fileAttributes, bool continueOnNotExist, PathFormat pathFormat)
internal static void SetAttributesCore(bool isFolder, KernelTransaction transaction, string path, FileAttributes fileAttributes, PathFormat pathFormat)
{
string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck);
var pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck);

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

// SetFileAttributes()
// In the ANSI version of this function, the name is limited to MAX_PATH characters.
@@ -140,13 +137,12 @@ namespace Alphaleonis.Win32.Filesystem
// 2013-01-13: MSDN confirms LongPath usage.

? NativeMethods.SetFileAttributes(pathLp, fileAttributes)
: NativeMethods.SetFileAttributesTransacted(pathLp, fileAttributes, transaction.SafeHandle)))
{
if (continueOnNotExist)
return;
: NativeMethods.SetFileAttributesTransacted(pathLp, fileAttributes, transaction.SafeHandle);

uint lastError = (uint)Marshal.GetLastWin32Error();

var lastError = (uint) Marshal.GetLastWin32Error();
if (!success)
{
switch (lastError)
{
// MSDN: .NET 3.5+: ArgumentException: FileSystemInfo().Attributes
@@ -155,7 +151,7 @@ namespace Alphaleonis.Win32.Filesystem

case Win32Errors.ERROR_FILE_NOT_FOUND:
if (isFolder)
lastError = (int)Win32Errors.ERROR_PATH_NOT_FOUND;
lastError = (int) Win32Errors.ERROR_PATH_NOT_FOUND;

// MSDN: .NET 3.5+: DirectoryNotFoundException: The specified path is invalid, (for example, it is on an unmapped drive).
// MSDN: .NET 3.5+: FileNotFoundException: The file cannot be found.


+ 2
- 2
AlphaFS/Filesystem/FileInfo Class/FileInfo.Replace.cs 查看文件

@@ -78,7 +78,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public FileInfo Replace(string destinationFileName, string destinationBackupFileName, PathFormat pathFormat)
{
var options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck;
const GetFullPathOptions options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck;

string destinationFileNameLp = Path.GetExtendedLengthPathCore(Transaction, destinationFileName, pathFormat, options);
string destinationBackupFileNameLp = destinationBackupFileName != null
@@ -105,7 +105,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public FileInfo Replace(string destinationFileName, string destinationBackupFileName, bool ignoreMetadataErrors, PathFormat pathFormat)
{
var options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck;
const GetFullPathOptions options = GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck;

string destinationFileNameLp = Path.GetExtendedLengthPathCore(Transaction, destinationFileName, pathFormat, options);
string destinationBackupFileNameLp = destinationBackupFileName != null


+ 4
- 4
AlphaFS/Filesystem/FileSystemInfo.cs 查看文件

@@ -266,7 +266,7 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
set
{
File.SetAttributesCore(IsDirectory, Transaction, LongFullName, value, false, PathFormat.LongFullPath);
File.SetAttributesCore(IsDirectory, Transaction, LongFullName, value, PathFormat.LongFullPath);
Reset();
}
}
@@ -547,7 +547,7 @@ namespace Alphaleonis.Win32.Filesystem
#region DisplayPath

/// <summary>Returns the path as a string.</summary>
protected internal string DisplayPath { get; set; }
protected internal string DisplayPath { get; protected set; }

#endregion // DisplayPath

@@ -590,7 +590,7 @@ namespace Alphaleonis.Win32.Filesystem
#region IsDirectory

/// <summary>[AlphaFS] The initial "IsDirectory" indicator that was passed to the constructor.</summary>
protected internal bool IsDirectory { get; set; }
protected bool IsDirectory { get; set; }

#endregion // IsDirectory

@@ -604,7 +604,7 @@ namespace Alphaleonis.Win32.Filesystem
#region Transaction

/// <summary>[AlphaFS] Represents the KernelTransaction that was passed to the constructor.</summary>
public KernelTransaction Transaction { get; set; }
protected KernelTransaction Transaction { get; set; }

#endregion // Transaction



+ 12
- 12
AlphaFS/Filesystem/Native Methods/NativeMethods.VolumeManagement.cs 查看文件

@@ -53,7 +53,7 @@ namespace Alphaleonis.Win32.Filesystem
[SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")]
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "DeleteVolumeMountPointW"), SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
internal extern static bool DeleteVolumeMountPoint([MarshalAs(UnmanagedType.LPWStr)] string lpszVolumeMountPoint);
internal static extern bool DeleteVolumeMountPoint([MarshalAs(UnmanagedType.LPWStr)] string lpszVolumeMountPoint);

/// <summary>Retrieves the name of a volume on a computer. FindFirstVolume is used to begin scanning the volumes of a computer.</summary>
/// <returns>
@@ -64,7 +64,7 @@ namespace Alphaleonis.Win32.Filesystem
/// <remarks>Minimum supported server: Windows Server 2003 [desktop apps only]</remarks>
[SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")]
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "FindFirstVolumeW"), SuppressUnmanagedCodeSecurity]
internal extern static SafeFindVolumeHandle FindFirstVolume(StringBuilder lpszVolumeName, [MarshalAs(UnmanagedType.U4)] uint cchBufferLength);
internal static extern SafeFindVolumeHandle FindFirstVolume(StringBuilder lpszVolumeName, [MarshalAs(UnmanagedType.U4)] uint cchBufferLength);

/// <summary>Retrieves the name of a mounted folder on the specified volume. FindFirstVolumeMountPoint is used to begin scanning the mounted folders on a volume.</summary>
/// <returns>
@@ -75,7 +75,7 @@ namespace Alphaleonis.Win32.Filesystem
/// <remarks>Minimum supported server: Windows Server 2003 [desktop apps only]</remarks>
[SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")]
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "FindFirstVolumeMountPointW"), SuppressUnmanagedCodeSecurity]
internal extern static SafeFindVolumeMountPointHandle FindFirstVolumeMountPoint([MarshalAs(UnmanagedType.LPWStr)] string lpszRootPathName, StringBuilder lpszVolumeMountPoint, [MarshalAs(UnmanagedType.U4)] uint cchBufferLength);
internal static extern SafeFindVolumeMountPointHandle FindFirstVolumeMountPoint([MarshalAs(UnmanagedType.LPWStr)] string lpszRootPathName, StringBuilder lpszVolumeMountPoint, [MarshalAs(UnmanagedType.U4)] uint cchBufferLength);

/// <summary>Continues a volume search started by a call to the FindFirstVolume function. FindNextVolume finds one volume per call.</summary>
/// <returns>
@@ -87,7 +87,7 @@ namespace Alphaleonis.Win32.Filesystem
[SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")]
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "FindNextVolumeW"), SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
internal extern static bool FindNextVolume(SafeFindVolumeHandle hFindVolume, StringBuilder lpszVolumeName, [MarshalAs(UnmanagedType.U4)] uint cchBufferLength);
internal static extern bool FindNextVolume(SafeFindVolumeHandle hFindVolume, StringBuilder lpszVolumeName, [MarshalAs(UnmanagedType.U4)] uint cchBufferLength);

/// <summary>Continues a mounted folder search started by a call to the FindFirstVolumeMountPoint function. FindNextVolumeMountPoint finds one mounted folder per call.</summary>
/// <returns>
@@ -100,7 +100,7 @@ namespace Alphaleonis.Win32.Filesystem
[SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")]
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "FindNextVolumeMountPointW"), SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
internal extern static bool FindNextVolumeMountPoint(SafeFindVolumeMountPointHandle hFindVolume, StringBuilder lpszVolumeName, [MarshalAs(UnmanagedType.U4)] uint cchBufferLength);
internal static extern bool FindNextVolumeMountPoint(SafeFindVolumeMountPointHandle hFindVolume, StringBuilder lpszVolumeName, [MarshalAs(UnmanagedType.U4)] uint cchBufferLength);

/// <summary>Closes the specified volume search handle.</summary>
/// <remarks>
@@ -114,7 +114,7 @@ namespace Alphaleonis.Win32.Filesystem
[SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")]
[DllImport("kernel32.dll", SetLastError = false, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
internal extern static bool FindVolumeClose(IntPtr hFindVolume);
internal static extern bool FindVolumeClose(IntPtr hFindVolume);

/// <summary>Closes the specified mounted folder search handle.</summary>
/// <remarks>
@@ -129,7 +129,7 @@ namespace Alphaleonis.Win32.Filesystem
[SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")]
[DllImport("kernel32.dll", SetLastError = false, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
internal extern static bool FindVolumeMountPointClose(IntPtr hFindVolume);
internal static extern bool FindVolumeMountPointClose(IntPtr hFindVolume);

/// <summary>
/// Determines whether a disk drive is a removable, fixed, CD-ROM, RAM disk, or network drive.
@@ -149,7 +149,7 @@ namespace Alphaleonis.Win32.Filesystem
[SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")]
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetDriveTypeW"), SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.U4)]
internal extern static DriveType GetDriveType([MarshalAs(UnmanagedType.LPWStr)] string lpRootPathName);
internal static extern DriveType GetDriveType([MarshalAs(UnmanagedType.LPWStr)] string lpRootPathName);

/// <summary>
/// Retrieves a bitmask representing the currently available disk drives.
@@ -180,7 +180,7 @@ namespace Alphaleonis.Win32.Filesystem
[SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")]
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetVolumeInformationW"), SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
internal extern static bool GetVolumeInformation([MarshalAs(UnmanagedType.LPWStr)] string lpRootPathName, StringBuilder lpVolumeNameBuffer, [MarshalAs(UnmanagedType.U4)] uint nVolumeNameSize, [MarshalAs(UnmanagedType.U4)] out uint lpVolumeSerialNumber, [MarshalAs(UnmanagedType.U4)] out int lpMaximumComponentLength, [MarshalAs(UnmanagedType.U4)] out VolumeInfoAttributes lpFileSystemAttributes, StringBuilder lpFileSystemNameBuffer, [MarshalAs(UnmanagedType.U4)] uint nFileSystemNameSize);
internal static extern bool GetVolumeInformation([MarshalAs(UnmanagedType.LPWStr)] string lpRootPathName, StringBuilder lpVolumeNameBuffer, [MarshalAs(UnmanagedType.U4)] uint nVolumeNameSize, [MarshalAs(UnmanagedType.U4)] out uint lpVolumeSerialNumber, [MarshalAs(UnmanagedType.U4)] out int lpMaximumComponentLength, [MarshalAs(UnmanagedType.U4)] out VolumeInfoAttributes lpFileSystemAttributes, StringBuilder lpFileSystemNameBuffer, [MarshalAs(UnmanagedType.U4)] uint nFileSystemNameSize);

/// <summary>Retrieves information about the file system and volume associated with the specified file.</summary>
/// <returns>
@@ -194,7 +194,7 @@ namespace Alphaleonis.Win32.Filesystem
[SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")]
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "GetVolumeInformationByHandleW"), SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
internal extern static bool GetVolumeInformationByHandle(SafeFileHandle hFile, StringBuilder lpVolumeNameBuffer, [MarshalAs(UnmanagedType.U4)] uint nVolumeNameSize, [MarshalAs(UnmanagedType.U4)] out uint lpVolumeSerialNumber, [MarshalAs(UnmanagedType.U4)] out int lpMaximumComponentLength, out VolumeInfoAttributes lpFileSystemAttributes, StringBuilder lpFileSystemNameBuffer, [MarshalAs(UnmanagedType.U4)] uint nFileSystemNameSize);
internal static extern bool GetVolumeInformationByHandle(SafeFileHandle hFile, StringBuilder lpVolumeNameBuffer, [MarshalAs(UnmanagedType.U4)] uint nVolumeNameSize, [MarshalAs(UnmanagedType.U4)] out uint lpVolumeSerialNumber, [MarshalAs(UnmanagedType.U4)] out int lpMaximumComponentLength, out VolumeInfoAttributes lpFileSystemAttributes, StringBuilder lpFileSystemNameBuffer, [MarshalAs(UnmanagedType.U4)] uint nFileSystemNameSize);

/// <summary>Retrieves a volume GUID path for the volume that is associated with the specified volume mount point (drive letter, volume GUID path, or mounted folder).</summary>
/// <returns>
@@ -255,7 +255,7 @@ namespace Alphaleonis.Win32.Filesystem
[SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")]
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "SetVolumeLabelW"), SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
internal extern static bool SetVolumeLabel([MarshalAs(UnmanagedType.LPWStr)] string lpRootPathName, [MarshalAs(UnmanagedType.LPWStr)] string lpVolumeName);
internal static extern bool SetVolumeLabel([MarshalAs(UnmanagedType.LPWStr)] string lpRootPathName, [MarshalAs(UnmanagedType.LPWStr)] string lpVolumeName);

/// <summary>Associates a volume with a drive letter or a directory on another volume.</summary>
/// <remarks>Minimum supported client: Windows XP [desktop apps only].</remarks>
@@ -267,7 +267,7 @@ namespace Alphaleonis.Win32.Filesystem
[SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule")]
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "SetVolumeMountPointW"), SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
internal extern static bool SetVolumeMountPoint([MarshalAs(UnmanagedType.LPWStr)] string lpszVolumeMountPoint, [MarshalAs(UnmanagedType.LPWStr)] string lpszVolumeName);
internal static extern bool SetVolumeMountPoint([MarshalAs(UnmanagedType.LPWStr)] string lpszVolumeMountPoint, [MarshalAs(UnmanagedType.LPWStr)] string lpszVolumeName);

/// <summary>Retrieves information about MS-DOS device names.</summary>
/// <remarks>Minimum supported client: Windows XP [desktop apps only].</remarks>


+ 1
- 1
AlphaFS/Filesystem/Native Structures/FILETIME.cs 查看文件

@@ -67,7 +67,7 @@ namespace Alphaleonis.Win32.Filesystem
if (obj == null || GetType() != obj.GetType())
return false;

FILETIME other = obj is FILETIME ? (FILETIME)obj : new FILETIME();
FILETIME other = obj as FILETIME? ?? new FILETIME();

return (other.dwHighDateTime.Equals(dwHighDateTime) &&
other.dwLowDateTime.Equals(dwLowDateTime));


+ 1
- 1
AlphaFS/Filesystem/Path Class/Path.Constants.cs 查看文件

@@ -63,7 +63,7 @@ namespace Alphaleonis.Win32.Filesystem
public static readonly string StreamSeparator = StreamSeparatorChar.ToString(CultureInfo.CurrentCulture);

/// <summary>[AlphaFS] StreamDataLabel = ':$DATA' Provides a platform-specific Stream :$DATA label.</summary>
public static readonly string StreamDataLabel = ":$DATA";
public const string StreamDataLabel = ":$DATA";

/// <summary>[AlphaFS] StringTerminatorChar = '\0' String Terminator Suffix.</summary>
public const char StringTerminatorChar = '\0';


+ 3
- 4
AlphaFS/Filesystem/Path Class/Path.GetComponents.cs 查看文件

@@ -357,10 +357,9 @@ namespace Alphaleonis.Win32.Filesystem
if (path.StartsWith(LongPathPrefix, StringComparison.OrdinalIgnoreCase))
return GetLongPathCore(path.Substring(0, rootLengthPath), GetFullPathOptions.None);

if (path.StartsWith(LongPathUncPrefix, StringComparison.OrdinalIgnoreCase))
return GetLongPathCore(pathRp.Substring(0, rootLengthPathRp), GetFullPathOptions.None);

return path.Substring(0, rootLengthPath);
return path.StartsWith(LongPathUncPrefix, StringComparison.OrdinalIgnoreCase)
? GetLongPathCore(pathRp.Substring(0, rootLengthPathRp), GetFullPathOptions.None)
: path.Substring(0, rootLengthPath);
}

#endregion // GetPathRoot


+ 1
- 4
AlphaFS/Filesystem/Shell32.cs 查看文件

@@ -656,15 +656,12 @@ namespace Alphaleonis.Win32.Filesystem
[SecurityCritical]
public static bool PathFileExists(string path)
{
if (Utils.IsNullOrWhiteSpace(path))
return false;

// PathFileExists()
// In the ANSI version of this function, the name is limited to 248 characters.
// To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.
// 2013-01-13: MSDN does not confirm LongPath usage but a Unicode version of this function exists.

return NativeMethods.PathFileExists(Path.GetFullPathCore(null, path, GetFullPathOptions.AsLongPath | GetFullPathOptions.FullCheck | GetFullPathOptions.ContinueOnNonExist));
return !Utils.IsNullOrWhiteSpace(path) && NativeMethods.PathFileExists(Path.GetFullPathCore(null, path, GetFullPathOptions.AsLongPath | GetFullPathOptions.FullCheck | GetFullPathOptions.ContinueOnNonExist));
}




+ 1
- 1
AlphaFS/Filesystem/Volume.cs 查看文件

@@ -175,7 +175,7 @@ namespace Alphaleonis.Win32.Filesystem
// The deviceName cannot have a trailing backslash.
deviceName = Path.RemoveTrailingDirectorySeparator(deviceName, false);

var searchFilter = (deviceName != null);
var searchFilter = deviceName != null;

// Only process options if a device is supplied.
if (searchFilter)


+ 1
- 1
AlphaFS/Network/Enumerations/ResourceType.cs 查看文件

@@ -49,7 +49,7 @@ namespace Alphaleonis.Win32.Network
/// <summary>RESOURCETYPE_PRINT
/// <para>All print resources.</para>
/// </summary>
Print = 2,
Print = 2
}
}
}

+ 1
- 1
AlphaFS/Network/Enumerations/ShareInfoLevel.cs 查看文件

@@ -41,6 +41,6 @@ namespace Alphaleonis.Win32.Network
Info503 = 503,

/// <summary>Contains information about the shared resource.</summary>
Info1005 = 1005,
Info1005 = 1005
}
}

+ 1
- 1
AlphaFS/Network/Enumerations/ShareResourceTypes.cs 查看文件

@@ -86,6 +86,6 @@ namespace Alphaleonis.Win32.Network
/// <remarks>Windows 7, Windows Server 2008 R2, Windows Vista, Windows Server 2008, and Windows Server 2003: This flag is not supported.</remarks>
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Ca")]
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ca")]
EnableCa = 16384,
EnableCa = 16384
}
}

+ 2
- 2
AlphaFS/Network/Host Class/DistributedFileSystem.cs 查看文件

@@ -199,7 +199,7 @@ namespace Alphaleonis.Win32.Network
totalEntries = 0;

// When host == null, the local computer is used.
// However, the resulting OpenResourceInfo.Host property will be empty.
// However, the resulting Host property will be empty.
// So, explicitly state Environment.MachineName to prevent this.
// Furthermore, the UNC prefix: \\ is not required and always removed.
string stripUnc = Utils.IsNullOrWhiteSpace(host) ? Environment.MachineName : Path.GetRegularPathCore(host, GetFullPathOptions.CheckInvalidPathChars, false).Replace(Path.UncPrefix, string.Empty);
@@ -233,7 +233,7 @@ namespace Alphaleonis.Win32.Network
totalEntries = 0;

// When host == null, the local computer is used.
// However, the resulting OpenResourceInfo.Host property will be empty.
// However, the resulting Host property will be empty.
// So, explicitly state Environment.MachineName to prevent this.
// Furthermore, the UNC prefix: \\ is not required and always removed.
string stripUnc = Utils.IsNullOrWhiteSpace(domain) ? NativeMethods.ComputerDomain : Path.GetRegularPathCore(domain, GetFullPathOptions.CheckInvalidPathChars, false).Replace(Path.UncPrefix, string.Empty);


+ 1
- 2
AlphaFS/Network/Host Class/EnumerateDrives.cs 查看文件

@@ -73,10 +73,9 @@ namespace Alphaleonis.Win32.Network
(FunctionData functionData, out SafeGlobalMemoryBufferHandle buffer, int prefMaxLen, out uint entriesRead, out uint totalEntries, out uint resume) =>
{
// When host == null, the local computer is used.
// However, the resulting OpenResourceInfo.Host property will be empty.
// However, the resulting Host property will be empty.
// So, explicitly state Environment.MachineName to prevent this.
// Furthermore, the UNC prefix: \\ is not required and always removed.

string stripUnc = Utils.IsNullOrWhiteSpace(host) ? Environment.MachineName : Path.GetRegularPathCore(host, GetFullPathOptions.CheckInvalidPathChars, false).Replace(Path.UncPrefix, string.Empty);

return NativeMethods.NetServerDiskEnum(stripUnc, 0, out buffer, NativeMethods.MaxPreferredLength, out entriesRead, out totalEntries, out resume);


+ 1
- 1
AlphaFS/Network/Host Class/EnumerateOpenResources.cs 查看文件

@@ -98,7 +98,7 @@ namespace Alphaleonis.Win32.Network
(FunctionData functionData, out SafeGlobalMemoryBufferHandle buffer, int prefMaxLen, out uint entriesRead, out uint totalEntries, out uint resumeHandle) =>
{
// When host == null, the local computer is used.
// However, the resulting OpenResourceInfo.Host property will be empty.
// However, the resulting Host property will be empty.
// So, explicitly state Environment.MachineName to prevent this.
// Furthermore, the UNC prefix: \\ is not required and always removed.
string stripUnc = Utils.IsNullOrWhiteSpace(host) ? Environment.MachineName : Path.GetRegularPathCore(host, GetFullPathOptions.CheckInvalidPathChars, false).Replace(Path.UncPrefix, string.Empty);


+ 12
- 15
AlphaFS/Network/Host Class/ServerMessageBlock.cs 查看文件

@@ -168,7 +168,7 @@ namespace Alphaleonis.Win32.Network
[SecurityCritical]
public static ShareInfo GetShareInfo(string uncPath, bool continueOnException)
{
string[] unc = GetHostShareFromPath(uncPath);
var unc = GetHostShareFromPath(uncPath);
return GetShareInfoCore(ShareInfoLevel.Info503, unc[0], unc[1], continueOnException);
}

@@ -180,7 +180,7 @@ namespace Alphaleonis.Win32.Network
[SecurityCritical]
public static ShareInfo GetShareInfo(ShareInfoLevel shareLevel, string uncPath, bool continueOnException)
{
string[] unc = GetHostShareFromPath(uncPath);
var unc = GetHostShareFromPath(uncPath);
return GetShareInfoCore(shareLevel, unc[0], unc[1], continueOnException);
}

@@ -213,7 +213,7 @@ namespace Alphaleonis.Win32.Network

#region EnumerateOpenConnectionsCore

/// <summary>Enumerates open connections from the specified host.</summary>
/// <summary>Enumerates open connections from the specified host and <paramref name="share"/>.</summary>
/// <returns><see cref="OpenConnectionInfo"/> connection information from the specified <paramref name="host"/>.</returns>
/// <exception cref="ArgumentNullException"/>
/// <exception cref="NetworkInformationException"/>
@@ -241,6 +241,7 @@ namespace Alphaleonis.Win32.Network
return NativeMethods.NetConnectionEnum(stripUnc, functionData.ExtraData1, 1, out buffer, NativeMethods.MaxPreferredLength, out entriesRead, out totalEntries, out resumeHandle);

},

continueOnException);
}

@@ -260,16 +261,14 @@ namespace Alphaleonis.Win32.Network
internal static IEnumerable<ShareInfo> EnumerateSharesCore(string host, ShareType shareType, bool continueOnException)
{
// When host == null, the local computer is used.
// However, the resulting OpenResourceInfo.Host property will be empty.
// However, the resulting Host property will be empty.
// So, explicitly state Environment.MachineName to prevent this.
// Furthermore, the UNC prefix: \\ is not required and always removed.
string stripUnc = Utils.IsNullOrWhiteSpace(host)
? Environment.MachineName
: Path.GetRegularPathCore(host, GetFullPathOptions.CheckInvalidPathChars, false).Replace(Path.UncPrefix, string.Empty);
var stripUnc = Utils.IsNullOrWhiteSpace(host) ? Environment.MachineName : Path.GetRegularPathCore(host, GetFullPathOptions.CheckInvalidPathChars, false).Replace(Path.UncPrefix, string.Empty);

var fd = new FunctionData();
bool hasItems = false;
bool yieldAll = shareType == ShareType.All;
var hasItems = false;
var yieldAll = shareType == ShareType.All;

// Try SHARE_INFO_503 structure.
foreach (var si in EnumerateNetworkObjectCore(fd, (NativeMethods.SHARE_INFO_503 structure, SafeGlobalMemoryBufferHandle buffer) =>
@@ -323,14 +322,12 @@ namespace Alphaleonis.Win32.Network
return null;

// When host == null, the local computer is used.
// However, the resulting OpenResourceInfo.Host property will be empty.
// However, the resulting Host property will be empty.
// So, explicitly state Environment.MachineName to prevent this.
// Furthermore, the UNC prefix: \\ is not required and always removed.
string stripUnc = Utils.IsNullOrWhiteSpace(host)
? Environment.MachineName
: Path.GetRegularPathCore(host, GetFullPathOptions.CheckInvalidPathChars, false).Replace(Path.UncPrefix, string.Empty);
var stripUnc = Utils.IsNullOrWhiteSpace(host) ? Environment.MachineName : Path.GetRegularPathCore(host, GetFullPathOptions.CheckInvalidPathChars, false).Replace(Path.UncPrefix, string.Empty);

bool fallback = false;
var fallback = false;


startNetShareGetInfo:
@@ -338,7 +335,7 @@ namespace Alphaleonis.Win32.Network
SafeGlobalMemoryBufferHandle safeBuffer;

uint structureLevel = Convert.ToUInt16(shareLevel, CultureInfo.InvariantCulture);
uint lastError = NativeMethods.NetShareGetInfo(stripUnc, share, structureLevel, out safeBuffer);
var lastError = NativeMethods.NetShareGetInfo(stripUnc, share, structureLevel, out safeBuffer);

using (safeBuffer)
{


+ 0
- 1
AlphaFS/Network/Native Methods/NativeMethods.DistributedFileSystem.cs 查看文件

@@ -19,7 +19,6 @@
* THE SOFTWARE.
*/

using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Security;


+ 1
- 1
AlphaFS/Resources.Designer.cs 查看文件

@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
// Runtime Version:4.0.30319.34209
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.


+ 2
- 3
AlphaFS/SafeNativeMemoryBufferHandle.cs 查看文件

@@ -30,14 +30,13 @@ namespace Alphaleonis.Win32
{
#region Private Fields

private int m_capacity;
private readonly int m_capacity;

#endregion

#region Constructors

protected SafeNativeMemoryBufferHandle(bool ownsHandle)
: base(ownsHandle)
protected SafeNativeMemoryBufferHandle(bool ownsHandle) : base(ownsHandle)
{
}



+ 9
- 9
AlphaFS/Security/Crc64.cs 查看文件

@@ -42,8 +42,7 @@ namespace Alphaleonis.Win32.Security
private ulong m_hash;

/// <summary>Initializes a new instance of <see cref="Crc64"/> </summary>
public Crc64()
: this(Iso3309Polynomial, DefaultSeed)
public Crc64() : this(Iso3309Polynomial, DefaultSeed)
{
}

@@ -53,7 +52,7 @@ namespace Alphaleonis.Win32.Security
private Crc64(ulong polynomial, ulong seed)
{
m_table = InitializeTable(polynomial);
this.m_seed = m_hash = seed;
m_seed = m_hash = seed;
}

/// <summary>
@@ -106,11 +105,13 @@ namespace Alphaleonis.Win32.Security
private static ulong CalculateHash(ulong seed, ulong[] table, IList<byte> buffer, int start, int size)
{
var hash = seed;
for (var i = start; i < start + size; i++)

for (var i = start; i < start + size; i++)
unchecked
{
hash = (hash >> 8) ^ table[(buffer[i] ^ hash) & 0xff];
}

return hash;
}

@@ -151,12 +152,11 @@ namespace Alphaleonis.Win32.Security
var createTable = new ulong[256];
for (var i = 0; i < 256; ++i)
{
var entry = (ulong)i;
var entry = (ulong) i;

for (var j = 0; j < 8; ++j)
if ((entry & 1) == 1)
entry = (entry >> 1) ^ polynomial;
else
entry = entry >> 1;
entry = (entry & 1) == 1 ? (entry >> 1) ^ polynomial : entry >> 1;

createTable[i] = entry;
}



+ 16
- 24
AlphaFS/Security/InternalPrivilegeEnabler.cs 查看文件

@@ -43,7 +43,7 @@ namespace Alphaleonis.Win32.Security
if (privilegeName == null)
throw new ArgumentNullException("privilegeName");

_mPrivilege = privilegeName;
EnabledPrivilege = privilegeName;
AdjustPrivilege(true);
}

@@ -55,12 +55,12 @@ namespace Alphaleonis.Win32.Security
{
try
{
if (_mPrivilege != null)
if (EnabledPrivilege != null)
AdjustPrivilege(false);
}
finally
{
_mPrivilege = null;
EnabledPrivilege = null;
}
}

@@ -71,31 +71,23 @@ namespace Alphaleonis.Win32.Security
{
using (WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent(TokenAccessLevels.Query | TokenAccessLevels.AdjustPrivileges))
{
if (currentIdentity != null)
{
IntPtr hToken = currentIdentity.Token;
TokenPrivileges newPrivilege = new TokenPrivileges();
TokenPrivileges mOldPrivilege = new TokenPrivileges();
newPrivilege.PrivilegeCount = 1;
newPrivilege.Luid = Filesystem.NativeMethods.LongToLuid(_mPrivilege.LookupLuid());
newPrivilege.Attributes = (uint)(enable ? 2 : 0); // 2 = SePrivilegeEnabled;
IntPtr hToken = currentIdentity.Token;
TokenPrivileges newPrivilege = new TokenPrivileges();
TokenPrivileges mOldPrivilege = new TokenPrivileges();
newPrivilege.PrivilegeCount = 1;
newPrivilege.Luid = Filesystem.NativeMethods.LongToLuid(EnabledPrivilege.LookupLuid());
newPrivilege.Attributes = (uint)(enable ? 2 : 0); // 2 = SePrivilegeEnabled;

uint length;
if (!NativeMethods.AdjustTokenPrivileges(hToken, false, ref newPrivilege, (uint) Marshal.SizeOf(mOldPrivilege), out mOldPrivilege, out length))
NativeError.ThrowException(Marshal.GetLastWin32Error());
uint length;
if (!NativeMethods.AdjustTokenPrivileges(hToken, false, ref newPrivilege, (uint) Marshal.SizeOf(mOldPrivilege), out mOldPrivilege, out length))
NativeError.ThrowException(Marshal.GetLastWin32Error());

// If no privilege was changed, we don't want to reset it.
if (mOldPrivilege.PrivilegeCount == 0)
_mPrivilege = null;
}
// If no privilege was changed, we don't want to reset it.
if (mOldPrivilege.PrivilegeCount == 0)
EnabledPrivilege = null;
}
}

public Privilege EnabledPrivilege
{
get { return _mPrivilege; }
}

private Privilege _mPrivilege;
public Privilege EnabledPrivilege { get; private set; }
}
}

+ 1
- 1
AlphaFS/Security/Privilege.cs 查看文件

@@ -490,5 +490,5 @@ namespace Alphaleonis.Win32.Security
}

#endregion // Privilege
};
}
}

+ 10
- 10
AlphaFS/Win32Errors.cs 查看文件

@@ -222,8 +222,8 @@ namespace Alphaleonis.Win32
//public const uint ERROR_SIGNAL_REFUSED = 156;
//public const uint ERROR_DISCARDED = 157;

/// <summary>(158) The segment is already unlocked.</summary>
public const uint ERROR_NOT_LOCKED = 158;
// <summary>(158) The segment is already unlocked.</summary>
//public const uint ERROR_NOT_LOCKED = 158;

//public const uint ERROR_BAD_THREADID_ADDR = 159;
//public const uint ERROR_BAD_ARGUMENTS = 160;
@@ -259,7 +259,7 @@ namespace Alphaleonis.Win32
//public const uint ERROR_INFLOOP_IN_RELOC_CHAIN = 202;

/// <summary>(203) The system could not find the environment option that was entered.</summary>
public const uint ERROR_ENVVAR_NOT_FOUND = 203;
//public const uint ERROR_ENVVAR_NOT_FOUND = 203;

//public const uint ERROR_NO_SIGNAL_SENT = 205;
//public const uint ERROR_FILENAME_EXCED_RANGE = 206;
@@ -320,7 +320,7 @@ namespace Alphaleonis.Win32
//public const uint ERROR_IO_INCOMPLETE = 996;

/// <summary>(997) Overlapped I/O operation is in progress.</summary>
public const uint ERROR_IO_PENDING = 997;
//public const uint ERROR_IO_PENDING = 997;

//public const uint ERROR_NOACCESS = 998;
//public const uint ERROR_SWAPERROR = 999;
@@ -449,7 +449,7 @@ namespace Alphaleonis.Win32
//public const uint ERROR_JOURNAL_ENTRY_DELETED = 1181;

/// <summary>(1200) The specified device name is invalid.</summary>
public const uint ERROR_BAD_DEVICE = 1200;
//public const uint ERROR_BAD_DEVICE = 1200;

//public const uint ERROR_CONNECTION_UNAVAIL = 1201;
//public const uint ERROR_DEVICE_ALREADY_REMEMBERED = 1202;
@@ -460,7 +460,7 @@ namespace Alphaleonis.Win32
//public const uint ERROR_NOT_CONTAINER = 1207;

/// <summary>(1208) An extended error has occurred.</summary>
public const uint ERROR_EXTENDED_ERROR = 1208;
//public const uint ERROR_EXTENDED_ERROR = 1208;

//public const uint ERROR_INVALID_GROUPNAME = 1209;
//public const uint ERROR_INVALID_COMPUTERNAME = 1210;
@@ -477,7 +477,7 @@ namespace Alphaleonis.Win32
//public const uint ERROR_DUP_DOMAINNAME = 1221;

/// <summary>(1222) The network is not present or not started.</summary>
public const uint ERROR_NO_NETWORK = 1222;
//public const uint ERROR_NO_NETWORK = 1222;

//public const uint ERROR_CANCELLED = 1223;
//public const uint ERROR_USER_MAPPED_FILE = 1224;
@@ -3226,7 +3226,7 @@ namespace Alphaleonis.Win32
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa370674%28v=vs.85%29.aspx

/// <summary>(0) The operation completed successfully.</summary>
public const uint NERR_Success = 0;
public const uint NERR_Success = ERROR_SUCCESS;

///// <summary>The workstation driver is not installed.</summary>
//public const uint NERR_NetNotStarted = 2102;
@@ -3559,7 +3559,7 @@ namespace Alphaleonis.Win32
//public const uint NERR_SyncRequired = 2249;

/// <summary>(2250) The network connection could not be found.</summary>
public const uint NERR_UseNotFound = 2250;
//public const uint NERR_UseNotFound = 2250;

///// <summary>This asg_type is invalid.</summary>
//public const uint NERR_BadAsgType = 2251;
@@ -3646,7 +3646,7 @@ namespace Alphaleonis.Win32
//public const uint NERR_MultipleNets = 2300;

/// <summary>(2310) This shared resource does not exist.</summary>
public const uint NERR_NetNameNotFound = 2310;
//public const uint NERR_NetNameNotFound = 2310;

///// <summary>This device is not shared.</summary>
//public const uint NERR_DeviceNotShared = 2311;


+ 1
- 1
AlphaFS/app.config 查看文件

@@ -1,3 +1,3 @@
<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v2.0.50727" sku="Client"/></startup></configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/></startup></configuration>

+ 1
- 1
NTFSSecurity/NTFSSecurity.csproj 查看文件

@@ -22,7 +22,7 @@
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\..\..\Program Files\WindowsPowerShell\Modules\NTFSSecurity\</OutputPath>
<OutputPath>..\..\..\..\..\..\Program Files\WindowsPowerShell\Modules\NTFSSecurity\</OutputPath>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>


Loading…
取消
儲存