/ * Copyright ( C ) 2 0 0 8 - 2 0 1 6 Peter Palotas , Jeffrey Jangli , Alexandr Normuradov
*
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the "Software" ) , to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED "AS IS" , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE .
* /
using System ;
using System.Diagnostics.CodeAnalysis ;
using System.Runtime.InteropServices ;
using System.Security ;
namespace Alphaleonis.Win32.Filesystem
{
public static partial class File
{
#region CreateHardlink
/// <summary>[AlphaFS] Establishes a hard link between an existing file and a new file. This function is only supported on the NTFS file system, and only for files, not directories.</summary>
/// <param name="fileName">The name of the new file. This parameter cannot specify the name of a directory.</param>
/// <param name="existingFileName">The name of the existing file. This parameter cannot specify the name of a directory.</param>
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hardlink")]
[SecurityCritical]
public static void CreateHardlink ( string fileName , string existingFileName , PathFormat pathFormat )
{
CreateHardlinkCore ( null , fileName , existingFileName , pathFormat ) ;
}
/// <summary>[AlphaFS] Establishes a hard link between an existing file and a new file. This function is only supported on the NTFS file system, and only for files, not directories.</summary>
/// <param name="fileName">The name of the new file. This parameter cannot specify the name of a directory.</param>
/// <param name="existingFileName">The name of the existing file. This parameter cannot specify the name of a directory.</param>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hardlink")]
[SecurityCritical]
public static void CreateHardlink ( string fileName , string existingFileName )
{
CreateHardlinkCore ( null , fileName , existingFileName , PathFormat . RelativePath ) ;
}
/// <summary>
/// [AlphaFS] Establishes a hard link between an existing file and a new file. This function is only supported on the NTFS file system,
/// and only for files, not directories.
/// </summary>
/// <param name="transaction">The transaction.</param>
/// <param name="fileName">The name of the new file. This parameter cannot specify the name of a directory.</param>
/// <param name="existingFileName">The name of the existing file. This parameter cannot specify the name of a directory.</param>
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hardlink")]
[SecurityCritical]
public static void CreateHardlinkTransacted ( KernelTransaction transaction , string fileName , string existingFileName , PathFormat pathFormat )
{
CreateHardlinkCore ( transaction , fileName , existingFileName , pathFormat ) ;
}
/// <summary>
/// [AlphaFS] Establishes a hard link between an existing file and a new file. This function is only supported on the NTFS file system,
/// and only for files, not directories.
/// </summary>
/// <param name="transaction">The transaction.</param>
/// <param name="fileName">The name of the new file. This parameter cannot specify the name of a directory.</param>
/// <param name="existingFileName">The name of the existing file. This parameter cannot specify the name of a directory.</param>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hardlink")]
[SecurityCritical]
public static void CreateHardlinkTransacted ( KernelTransaction transaction , string fileName , string existingFileName )
{
CreateHardlinkCore ( transaction , fileName , existingFileName , PathFormat . RelativePath ) ;
}
#endregion // CreateHardlink
#region Internal Methods
/// <summary>Establish a hard link between an existing file and a new file. This function
/// is only supported on the NTFS file system, and only for files, not directories.
/// </summary>
/// <exception cref="NotSupportedException"/>
/// <param name="transaction">The transaction.</param>
/// <param name="fileName">The name of the new file. This parameter cannot specify the name of a directory.</param>
/// <param name="existingFileName">The name of the existing file. This parameter cannot specify the name of a directory.</param>
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hardlink")]
[SecurityCritical]
internal static void CreateHardlinkCore ( KernelTransaction transaction , string fileName , string existingFileName , PathFormat pathFormat )
{
const GetFullPathOptions options = GetFullPathOptions . RemoveTrailingDirectorySeparator | GetFullPathOptions . FullCheck ;
string fileNameLp = Path . GetExtendedLengthPathCore ( transaction , fileName , pathFormat , options ) ;
string existingFileNameLp = Path . GetExtendedLengthPathCore ( transaction , existingFileName , pathFormat , options ) ;
if ( ! ( transaction = = null | | ! NativeMethods . IsAtLeastWindowsVista
// CreateHardLink() / CreateHardLinkTransacted()
// In the ANSI version of this function, the name is limited to MAX_PATH characters.
// To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path.
// 2013-01-13: MSDN does not confirm LongPath usage but a Unicode version of this function exists.
? NativeMethods . CreateHardLink ( fileNameLp , existingFileNameLp , IntPtr . Zero )
: NativeMethods . CreateHardLinkTransacted ( fileNameLp , existingFileNameLp , IntPtr . Zero , transaction . SafeHandle ) ) )
{
int lastError = Marshal . GetLastWin32Error ( ) ;
switch ( ( uint ) lastError )
{
case Win32Errors . ERROR_INVALID_FUNCTION :
throw new NotSupportedException ( Resources . HardLinks_Not_Supported ) ;
default :
NativeError . ThrowException ( lastError , fileNameLp , existingFileName ) ;
break ;
}
}
}
#endregion // Internal Methods
}
}