Removes hacky solution

This commit is contained in:
Karolis2011
2019-08-20 18:40:41 +03:00
parent 568c45ad87
commit a05d8ce8bf
2 changed files with 1 additions and 325 deletions

View File

@@ -1,259 +0,0 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace ASS.Server.Helpers
{
// TODO: Remove when https://github.com/joshudson/Emet/pull/3 is merged
internal class EmetNativeMethods
{
[StructLayout(LayoutKind.Sequential)]
internal struct dirent64 {
internal ulong d_ino;
internal ulong d_off;
internal ushort d_reclen;
internal byte d_type;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=256)]
internal byte[] d_name;
}
[StructLayout(LayoutKind.Sequential)]
internal struct statbuf64 {
internal ulong st_dev;
internal ulong st_ino;
internal ulong st_nlink;
internal uint st_mode;
internal uint st_uid;
internal uint st_gid;
internal ulong st_rdev;
internal ulong st_size;
internal ulong st_blksize;
internal ulong st_blocks; /* number of 512 byte blocks */
internal long st_atime;
internal ulong st_atime_nsec;
internal long st_mtime;
internal ulong st_mtime_nsec;
internal long st_ctime;
internal ulong st_ctime_nsec;
internal ulong st_glibc_reserved0;
internal ulong st_glibc_reserved1;
internal ulong st_glibc_reserved2;
};
internal const int statbuf_version = 1;
[DllImport("libc.so.6", SetLastError=true)]
internal static extern IntPtr opendir([MarshalAs(UnmanagedType.LPArray)] byte[] path);
[DllImport("libc.so.6", SetLastError=true)]
internal static extern IntPtr closedir(IntPtr dir);
[DllImport("libc.so.6", SetLastError=true)]
internal static extern int readdir64_r(IntPtr dir, ref dirent64 entry, out IntPtr result);
[DllImport("libc.so.6", SetLastError=true)]
internal static extern int __xstat64(int version, [MarshalAs(UnmanagedType.LPArray)] byte[] file, out statbuf64 buf);
[DllImport("libc.so.6", SetLastError=true)]
internal static extern int __lxstat64(int version, [MarshalAs(UnmanagedType.LPArray)] byte[] file, out statbuf64 buf);
[DllImport("libc.so.6", SetLastError=true)]
internal static extern int __fxstat64(int version, IntPtr file, out statbuf64 buf);
[DllImport("libc.so.6", SetLastError=true)]
internal static extern int rename([MarshalAs(UnmanagedType.LPArray)] byte[] from, [MarshalAs(UnmanagedType.LPArray)] byte[] to);
[DllImport("libc.so.6", SetLastError=true)]
internal static extern int link([MarshalAs(UnmanagedType.LPArray)] byte[] filename, [MarshalAs(UnmanagedType.LPArray)] byte[] linktarget);
[DllImport("libc.so.6", SetLastError=true)]
internal static extern int symlink([MarshalAs(UnmanagedType.LPArray)] byte[] filename, [MarshalAs(UnmanagedType.LPArray)] byte[] linktarget);
[DllImport("libc.so.6", SetLastError=true)]
internal static extern long readlink([MarshalAs(UnmanagedType.LPArray)] byte[] filename, [MarshalAs(UnmanagedType.LPArray)] byte[] buffer, long buflen);
internal const int FileFsVolumeInformation = 1;
internal const int FileBasicInformation = 4;
internal const int FileStandardInformation = 5;
internal const int FileInternalInformation = 6;
internal const int FileAllInformation = 18;
internal static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
internal const uint MOVEFILE_REPLACE_EXISTING = 1;
internal const uint FILE_SHARE_READ = 1;
internal const uint FILE_SHARE_WRITE = 2;
internal const uint FILE_SHARE_DELETE = 4;
internal const uint FILE_SHARE_ALL = 7;
internal const uint CREATE_ALWAYS = 2;
internal const uint CREATE_NEW = 1;
internal const uint OPEN_ALWAYS = 4;
internal const uint OPEN_EXISTING = 3;
internal const uint TRUNCATE_EXISTING = 5;
internal const uint FILE_ATTRIBUTE_DIRECTORY = 16;
internal const uint FILE_ATTRIBUTE_REPARSE_POINT = 1024;
internal const uint FILE_READ_ATTRIBUTES = 128;
internal const uint FILE_FLAG_BACKUP_SEMANTICS = 0x2000000;
internal const uint FILE_FLAG_OPEN_NO_RECALL = 0x1000000;
internal const uint FILE_FLAG_OPEN_REPARSE_POINT = 0x200000;
internal const uint SYMBOLIC_LINK_FLAG_DIRECTORY = 1;
internal const uint SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE = 2;
internal const uint FSCTL_GET_REPARSE_POINT = 589992;
[StructLayout(LayoutKind.Sequential)]
internal struct IO_STATUS_BLOCK {
internal IntPtr Status;
internal UIntPtr Information;
}
[StructLayout(LayoutKind.Sequential)]
internal struct REPARSE_DATA_BUFFER_SYMLINK {
internal uint ReparseTag;
internal ushort ReparseDataLength;
internal ushort Reserved;
internal ushort SubstituteNameOffset;
internal ushort SubstituteNameLength;
internal ushort PrintNameOffset;
internal ushort PrintNameLength;
internal uint Flags;
}
[StructLayout(LayoutKind.Sequential)]
internal struct FILE_BASIC_INFORMATION {
internal ulong CreationTime; // 100ns units since Jan 1 1601
internal ulong LastAccessTime;
internal ulong LastWriteTime;
internal ulong ChangeTime;
internal uint FileAttributes;
}
[StructLayout(LayoutKind.Sequential)]
internal struct FILE_STANDARD_INFORMATION {
internal ulong AllocationSize;
internal ulong EndOfFile;
internal uint NumberOfLinks;
internal bool DeletePending;
internal bool Directory;
}
[StructLayout(LayoutKind.Sequential)]
internal struct FILE_INTERNAL_INFORMATION {
internal ulong file_index;
}
[StructLayout(LayoutKind.Sequential)]
internal struct FILE_FS_VOLUME_INFORMATION {
internal ulong VolumeCreationTime;
internal uint VolumeSerialNumber;
internal uint VolumeLabelLength;
internal bool SupportsObjects;
}
[StructLayout(LayoutKind.Sequential)]
internal struct FILE_EA_INFORMATION {
internal uint EaSize;
}
[StructLayout(LayoutKind.Sequential)]
internal struct FILE_ACCESS_INFORMATION {
internal uint AccessMask;
}
[StructLayout(LayoutKind.Sequential)]
internal struct FILE_POSITION_INFORMATION {
internal ulong CurrentByteOffset;
}
[StructLayout(LayoutKind.Sequential)]
internal struct FILE_MODE_INFORMATION {
internal uint Mode;
}
[StructLayout(LayoutKind.Sequential)]
internal struct FILE_ALIGNMENT_INFORMATION {
internal uint AlignmentRequirement;
}
[StructLayout(LayoutKind.Sequential)]
internal struct FILE_ALL_INFORMATION {
internal FILE_BASIC_INFORMATION BasicInformation;
internal FILE_STANDARD_INFORMATION StandardInformation;
internal FILE_INTERNAL_INFORMATION InternalInformation;
internal FILE_EA_INFORMATION EaInformation;
internal FILE_ACCESS_INFORMATION AccessInformation;
internal FILE_POSITION_INFORMATION PositionInformation;
internal FILE_MODE_INFORMATION ModeInformation;
internal FILE_ALIGNMENT_INFORMATION AlignmentInformation;
internal uint FileNameLength; // Variable structure
}
[StructLayout(LayoutKind.Sequential)]
internal struct FILETIME {
internal uint dwLowDateTime;
internal uint dwHighDateTime;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
internal struct WIN32_FIND_DATA {
internal uint dwFileAttributes;
internal FILETIME ftCreationTime;
internal FILETIME ftLastAccessTime;
internal FILETIME ftLastWriteTime;
internal uint nFileSizeHigh;
internal uint nFileSizeLow;
internal uint dwReserved0;
internal uint dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)]
internal string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=14)]
internal string cAlternateFileName;
}
[DllImport("ntdll.dll")]
internal static extern int NtQueryVolumeInformationFile(IntPtr handle, out IO_STATUS_BLOCK block, out FILE_FS_VOLUME_INFORMATION volume_info, int length, int Class);
[DllImport("ntdll.dll")]
internal static extern int NtQueryInformationFile(IntPtr handle, out IO_STATUS_BLOCK block, out FILE_BASIC_INFORMATION basic_info, int length, int Class);
[DllImport("ntdll.dll")]
internal static extern int NtQueryInformationFile(IntPtr handle, out IO_STATUS_BLOCK block, out FILE_STANDARD_INFORMATION standard_info, int length, int Class);
[DllImport("ntdll.dll")]
internal static extern int NtQueryInformationFile(IntPtr handle, out IO_STATUS_BLOCK block, out FILE_INTERNAL_INFORMATION internal_info, int length, int Class);
[DllImport("ntdll.dll")]
internal static extern int NtQueryInformationFile(IntPtr handle, out IO_STATUS_BLOCK block, out FILE_ALL_INFORMATION all_info, int length, int Class);
[DllImport("ntdll.dll")]
internal static extern int RtlNtStatusToDosError(int ntstatus);
[DllImport("kernel32.dll", SetLastError=true)]
internal static extern void SetLastError(int error);
[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
internal static extern IntPtr FindFirstFileW(string filename, out WIN32_FIND_DATA FindFileData);
[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
internal static extern byte FindNextFileW(IntPtr hFindFile, out WIN32_FIND_DATA FindFileData);
[DllImport("kernel32.dll", SetLastError=true)]
internal static extern byte FindClose(IntPtr hFindFile);
[DllImport("kernel32.dll", SetLastError=true)]
internal static extern byte MoveFileEx(string oldfilename, string newfilename, uint flags);
[DllImport("kernel32.dll", SetLastError=true)]
internal static extern byte CloseHandle(IntPtr hFindFile);
[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
internal static extern IntPtr CreateFileW(string filename, uint dwDesiredAccess, uint dwShareMode,
IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImport("kernel32.dll", SetLastError=true)]
internal static extern byte DeviceIoControl(IntPtr hDevice, uint dwIoControlCode, IntPtr inptr, uint inlen,
[MarshalAs(UnmanagedType.LPArray)] byte[] outdata, uint outlen, out uint returned, IntPtr overlapped);
[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
internal static extern byte CreateSymbolicLinkW(string lpSymlinkFileName, string lpTargetFileName, uint dwFlags);
[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
internal static extern byte CreateHardLinkW(string lpFileName, string lpExistingFileName, IntPtr lpSecurityAttributes);
}
}

View File

@@ -29,72 +29,7 @@ namespace ASS.Server.Helpers
{ {
if (targetHint == FileType.File || targetHint == FileType.Directory) if (targetHint == FileType.File || targetHint == FileType.Directory)
target = Path.GetRelativePath(Path.Combine(link, ".."), target); target = Path.GetRelativePath(Path.Combine(link, ".."), target);
CreateSymbolicLink(target, link, targetHint); FileSystem.CreateSymbolicLink(target, link, targetHint);
}
// TODO: Remove when https://github.com/joshudson/Emet/pull/3 is merged
///<summary>Creates a symbolic link to a file</summary>
///<param name="targetpath">The path to write to the symbolic link</param>
///<param name="linkpath">The path to create the new link at</param>
///<param name="targethint">The type of node the link is referring to</param>
///<exception cref="System.IO.IOException">An IO error occurred</exception>
///<exception cref="System.PlatformNotSupportedException">linkpath doesn't exist and targethint was neither File nor Directory and this platform uses explicit link types</exception>
///<remarks>If targetpath doesn't exist and targethint is not provided, this call will fail on Windows.</remarks>
public static void CreateSymbolicLink(string targetpath, string linkpath, FileType targethint = FileType.LinkTargetHintNotAvailable)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
var btargetpath = NameToByteArray(targetpath);
var blinkpath = NameToByteArray(linkpath);
if (EmetNativeMethods.symlink(btargetpath, blinkpath) != 0)
{
var errno = Marshal.GetLastWin32Error();
var ci = new System.ComponentModel.Win32Exception();
throw new IOException(ci.Message, errno);
}
} else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
uint flags = 0;
if (targethint != FileType.File && targethint != FileType.Directory)
{
if (!Path.IsPathRooted(targetpath))
{
var ldname = Path.GetDirectoryName(linkpath);
if (string.IsNullOrEmpty(ldname)) ldname = DirectoryEntry.CurrentDirectoryName;
targetpath = Path.Combine(ldname, targetpath);
}
var node = new DirectoryEntry(targetpath, FileSystem.FollowSymbolicLinks.Never);
var hint = (node.FileType == FileType.SymbolicLink) ? node.LinkTargetHint : node.FileType;
if (hint == FileType.Directory)
flags = EmetNativeMethods.SYMBOLIC_LINK_FLAG_DIRECTORY;
else if (hint != FileType.File)
throw new PlatformNotSupportedException("Windows can't handle symbolic links to file system nodes that don't exist.");
}
if (targethint == FileType.Directory)
flags = EmetNativeMethods.SYMBOLIC_LINK_FLAG_DIRECTORY;
if (0 == EmetNativeMethods.CreateSymbolicLinkW(linkpath, targetpath, flags))
{
var errno = (int)Marshal.GetLastWin32Error();
if (errno == 1314)
{
flags |= EmetNativeMethods.SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
if (0 != EmetNativeMethods.CreateSymbolicLinkW(linkpath, targetpath, flags))
return;
var errno2 = (int)Marshal.GetLastWin32Error();
if (errno2 != 1314 && errno2 != 1 && errno2 != 0xA0)
errno = errno2; // Try to get a better error
}
var ci = new System.ComponentModel.Win32Exception();
throw new IOException(ci.Message, unchecked((int)0x80070000 | errno));
}
}
}
internal static byte[] NameToByteArray(string name)
{
var count = Encoding.UTF8.GetByteCount(name);
var bytes = new byte[count + 1];
Encoding.UTF8.GetBytes(name, 0, name.Length, bytes, 0);
return bytes;
} }
} }
} }