Страницы

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

суббота, 6 октября 2018 г.

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

Нужно получить права на чтение и запись залоченого фолдера.
Или как сделать следующий код валидным:
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); }


Ответ

Ага, я нашёл, как 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.

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

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