#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.
Комментариев нет:
Отправить комментарий