Страницы

Поиск по вопросам

воскресенье, 1 декабря 2019 г.

Получить доступ к папке

#c_sharp #net #файловая_система


Нужно получить права на чтение и запись залоченого фолдера.

Или как сделать следующий код валидным:

        DirectoryInfo dir = new DirectoryInfo(@"D:/System Volume Information");

        foreach (var item in dir.GetDirectories())
        {
            Console.WriteLine(item.FullName);
        }


Желательно что бы работало с System Volume Information

Следующий код не работает тоже:

    [Flags]
    enum MoveFileFlags
    {
        MOVEFILE_REPLACE_EXISTING = 0x00000001,
        MOVEFILE_COPY_ALLOWED = 0x00000002,
        MOVEFILE_DELAY_UNTIL_REBOOT = 0x00000004,
        MOVEFILE_WRITE_THROUGH = 0x00000008,
        MOVEFILE_CREATE_HARDLINK = 0x00000010,
        MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x00000020
    }

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName,
MoveFileFlags dwFlags);

    static void Main(string[] args)
    {
        string path = @"D:/System Volume Information";

        DirectoryInfo dir = new DirectoryInfo(path);

        MoveFileEx(path, path + "2", MoveFileFlags.MOVEFILE_REPLACE_EXISTING);

        string msg = new Win32Exception(Marshal.GetLastWin32Error()).Message;

        Console.WriteLine(msg);
    }

    


Ответы

Ответ 1



Ага, я нашёл, как Far это делает. Он не просто запускает процесс от имени администратора (на самом деле, дочерний процесс, с которым связывается через pipe). Этот самый дочерний процесс, будучи запущенным от имени администратора, имеет право затребовать себе привилегии Backup и Restore (вот официальный метод, как сделать такое на чистом WinAPI). Что он и делает. Имея эти привилегии, дочерний процесс может делать всё. Мораль: вы можете ограничить в правах административный процесс, но он может снять ваши ограничения. Для читателей, вот работающий код: (разумеется, вы должны добавить манифест, как указано в ответе @Dmitry) class Program { static public void Main() { using (var outf = File.CreateText(@"D:\dirlist.txt")) { if (!RequestSeBackupPrivilege()) { outf.WriteLine("Cannot request privilege: "); return; } try { string path = @"D:\System Volume Information"; var dir = new DirectoryInfo(path); foreach (var item in dir.GetFileSystemInfos()) outf.WriteLine(item.FullName); } catch (Exception ex) { outf.WriteLine("Exception:"); outf.Write(ex); } } } static bool RequestSeBackupPrivilege() { LUID luid; if (!LookupPrivilegeValue(null, "SeBackupPrivilege", out luid)) return false; TOKEN_PRIVILEGES_SINGLE tp = new TOKEN_PRIVILEGES_SINGLE { PrivilegeCount = 1, Luid = luid, Attributes = SE_PRIVILEGE_ENABLED }; IntPtr hToken; return OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out hToken) && AdjustTokenPrivileges( hToken, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero) && (Marshal.GetLastWin32Error() != ERROR_NOT_ALL_ASSIGNED); } const int SE_PRIVILEGE_ENABLED = 0x00000002; const int TOKEN_QUERY = 0x00000008; const int TOKEN_ADJUST_PRIVILEGES = 0x00000020; const int ERROR_NOT_ALL_ASSIGNED = 1300; [DllImport("kernel32.dll", ExactSpelling = true)] static extern IntPtr GetCurrentProcess(); [StructLayout(LayoutKind.Sequential)] struct TOKEN_PRIVILEGES_SINGLE { public UInt32 PrivilegeCount; public LUID Luid; public UInt32 Attributes; } [StructLayout(LayoutKind.Sequential)] struct LUID { public uint LowPart; public int HighPart; } [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool LookupPrivilegeValue( string lpSystemName, string lpName, out LUID lpLuid); [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool OpenProcessToken( IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle); [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] static extern bool AdjustTokenPrivileges( IntPtr htok, bool disall, ref TOKEN_PRIVILEGES_SINGLE newst, int len, IntPtr prev, IntPtr relen); } Определения структур данных взяты на pinvoke.net.

Ответ 2



Насколько я помню, этот фолдер не залочен, а требует повышенных привилегий администратора. Чтобы повысить привилегии вашего приложения, добавьте в проект файл манифеста (выполнив Project -> Add New Item -> "Application Manifest File"), а в нем откорректируйте значение узла requestedExecutionLevel следующим образом:

Ответ 3



VladD прав. Это защищенная системная папка, доступ к которой осуществляется при помощи прав Local System. Вам нужно запустить свое приложение от Local System, сделать это можно следующими способами: Использовать планировщик задач (TaskScheduler). Написать службу и запустить приложение из нее. Внедриться в какой-нибудь LocalSystem-процесс и оттуда запустить свою программу. Использовать psexec (Sysinternals) с ключом -s.

Комментариев нет:

Отправить комментарий