Кодинг

Погружение в Dokan. Как сделать свою файловую систему для Windows без FUSE


В Linux, как известно, многие вещи реализованы как файлы в файловой системе. А если и не реализованы, то их можно реализовать самому при помощи FUSE. В Windows это менее принято, но если все же очень хочется смонтировать что-то как ФС, то это возможно. Я покажу, как этого добиться, используя C# и библиотеку Dokan.

Если знаком с утилитой CyberSafe Top Secret, то ты, наверное, тоже столкнулся с тем, что добавлять файлы в контейнер неудобно. Совсем другое дело — VeraCrypt: монтируешь локальный диск, и файлы шифруются на лету. Именно так будет работать наш проект.

 

Теория

Каждый раз, когда ты открываешь папку «Компьютер», файловый менеджер отправляет запрос ядру с просьбой сказать, какие есть диски. Как происходит общение с драйвером? Через диспетчер ввода-вывода. Любое приложение может отправить ему пакет с запросом (IRP, I/O Request Packet) и информацией, кому он предназначен. Диспетчер принимает этот запрос и передает его нужному драйверу.

Получив список занятых букв, файловый менеджер последовательно опрашивает систему о том, какие метки тома у этих дисков, сколько на них осталось места, какая файловая система и так далее. Каждый такой запрос передается первому драйверу в цепочке. Если тот не знает, что ответить, он спрашивает следующий, тот в свою очередь — дальше. И так, пока какой-либо из них не ответит, что нужная инфа найдена (или не найдена). В реальности эта схема несколько сложнее, но для общего понимания этого достаточно.

Любой драйвер средствами все того же диспетчера ввода-вывода может что-нибудь спросить у любого приложения, работающего в user-mode, что и используется в драйвере FUSE.

 

FUSE

Хоть мы и не будем использовать FUSE, в двух словах расскажу, что это такое. FUSE работает одним из драйверов в цепочке и позволяет быстро создать свою ФС без возни с драйвером, а еще такую ФС могут монтировать пользователи без прав рута.

Результат создания своего драйвера ФС

FUSE не является драйвером ФС и не отвечает на запросы самостоятельно, а передает их пользовательскому приложению, которое и отвечает на запрос. Ответ приложения отправляется обратно в ядро, а оттуда — приложению, которое запросило информацию.

 

Dokan

В теории существует версия FUSE для Windows, однако заставить ее работать мне не удалось. Возможно, это было бы само по себе интересным опытом, но я избрал другой путь.

Есть такой проект — Dokan. По сути, это тот же FUSE, но с кучей приятных дополнений. Во-первых, он ни разу за время его использования у меня не выдал ни одного синего экрана смерти. Во-вторых, есть библиотеки, которые позволяют работать с ним из самых разных языков, включая Delphi, Ruby, C# и Java (их ты найдешь на GitHub по ссылке выше). И в-третьих, разобраться с ним почти так же просто, как и с FUSE. Так что будем использовать его, библиотеку под C# и немного фантазии.

От изначального проекта Dokan сейчас осталось очень мало. После версии 0.6.0 появился серьезно доработанный форк под названием Dokany. Теперь жив только Dokany, и, соответственно, мы будем использовать его. В дальнейшем, говоря о Dokan, я буду подразумевать именно Dokany.

 

Подготовка

Чтобы использовать Dokan, нам понадобится драйвер. К нашему счастью, есть уже готовые собранные драйверы, которые нужно только установить. Тут есть три варианта. Первый — воспользоваться автоматическим установщиком. Второй — скачать собранные бинарники (они уже подписаны) и встроить их в свой установщик. Ну и третий — скачать исходный код, благо он открыт (часть проекта распространяется по лицензии LGPLv3, часть — по MIT), и собрать все самостоятельно.

Плюс такого подхода в том, что мы можем подписать готовый драйвер своей подписью, но на этом плюсы заканчиваются. Я выбрал первый вариант. Скачать установщик можно тут. Мастер в конце попросит перезагрузить компьютер, что мы и сделаем. Если после перезагрузки мы видим драйвер dokan1.sys, то все сделано правильно. Если нет — можно попробовать поставить вручную.

Загруженный драйвер dokan1.sys

Чтобы установить вручную, придется скачать более объемный файл. Кроме драйверов, он содержит и нужные тебе библиотеки (если ты знаешь C++), так что не спеши удалять его после установки.

Нас же сейчас интересует папка x64 (у тебя ведь 64 бита?). В ней — набор папок, как на картинке.

Содержимое папки x64

У меня Windows 8.1, так что иду в соответствующую папку (рекомендую Release) и, ткнув по inf-файлу правой кнопкой мышки, выбираю «Установить». Подтверждаю запрос UAC и жду окончания процесса, после чего перезагружаю машину.

Теперь установка должна пройти успешно. Если что-то не получилось — убедись, что ставишь ту версию драйвера.

Кроме Dokan, нам еще понадобится Visual Studio. Недавно вышла версия 2019, так что, даже если у тебя уже установлена, советую обновиться. С приготовлениями все, переходим к кодингу.

 

Кодинг

Открываем Visual Studio и создаем новый проект типа Console App (.NET Framework). На скриншоте видно, что целевой фреймворк — 4.5.2, но минимально поддерживаемый — 4.0. Так что, если твоя машина не поддерживает 4.5.2, ты знаешь, что делать.

Проект создали, и теперь нашему взору предстала заглушка метода Main. Ты ведь установил NuGet вместе со «Студией»? Если нет, устанавливай. Оттуда мы ставим пакет DokanNet (Tools → NuGet Package Manager → Manage NuGet Packages for Solution). Любители командной строки могут открыть PowerShell-консоль NuGet (Tools → NuGet Package Manager → Package Manager Console) и выполнить Install-Package DokanNet.

Чтобы создать свою ФС, нам нужен класс, реализующий IDokanOperations. Создаем новый класс (Ctrl+Shift+A) и добавляем туда using DokanDet;. Наш класс должен реализовывать интерфейс IDokanOperations, так что исправляем class XakepFSClass на class XakepFSClass : IDokanOperations.

Как ты видишь, в 10-й строке ошибка. Конечно, мы же унаследовали кучу методов от интерфейса, но не реализовали их. Я знаю, ты не хочешь объявлять каждый метод вручную, поэтому поставь курсор на неугодное выражение (IDokanOperations в 10-й строке) и нажми Alt-Enter. В появившемся меню выбери Implement interface.

Теперь порядок! Но все методы выкидывают исключение NotImplementedException, что нам никак не подходит. Давай-ка реализуем Hello World, а затем — ФС, хранящую все данные в JSON.

 

HelloWorldFS

Поскольку это просто Hello World, я не хочу изменять файл, который мы только что создали. Сделаем его копию, переименуем для лучшего восприятия (для переименования выбери файл в правой панели и нажми F2). Теперь откроем наш новый класс и переименуем и его, а то компилятор не поймет наши фокусы. У тебя должно получиться как на скриншоте.

Источник: xakep.ru

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *