Вторая жизнь Virtual Floppy Drive

  • Tutorial
Когда-то давно у меня была коллекция старинных версий Windows в виртуалках, и для переноса файлов между хост-машиной и этими виртуалками приходилось использовать дискету, потому что поддержка shared folders появилась только в Windows for Workgroups.

Перенос файлов через дискету был медленным и шумным, и моему восторгу не было предела, когда я нашёл драйвер Virtual Floppy Drive, позволяющий создать «виртуальный флопповод» и подключить его в VM как обычный. К сожалению, интерес автора к своему проекту угас в 2005, а в 2010 его сайт и емейл перестали существовать. С тех пор в мире Windows успело произойти много перемен:

  • Повсеместно стала использоваться 64-битная ОС, в которую невозможно загрузить 32-битный драйвер, скомпилированный в 2005;
  • Windows начиная с Vista SP1 стала требовать для загрузки драйверов либо цифровую подпись, либо муторные манипуляции, требующие перезагрузку системы;
  • Проект, написанный в Visual C++ 6, не собирается в современных версиях Visual Studio после автоматической конвертации.

Уже в 2011 в рассылке разработчиков ReactOS обсуждалось предоставление поддержки заброшенному проекту; но без согласия самого автора это произойти не могло, а автор к тому времени уже несколько лет как не подавал признаков жизни. Тогда же некий Andriy G. Tereshchenko создал неофициальное зеркало vfd.sourceforge.net с копией исчезнувшего сайта автора. Там на SourceForge до сих пор лежит версия 2005 г., и до сих пор постятся жалобы на то, что в Windows 7+ эта версия не работает.

Я захотел продолжить разработку VFD на github.com/tyomitch/vfd; даже если вам равнодушен сам VFD, то мой рассказ может вам помочь в «оживлении» других заброшенных проектов под Windows.

Компиляция


Visual Studio 2019 соглашается открыть vfd.dsw и сконвертировать составляющие его проекты в современный формат; но конвертация осуществляется не полностью, так что сконвертированные проекты отказываются компилироваться.

Я обнаружил следующие проблемы:

  • Некорректно сконвертировался вызов Message Compiler (mc $(InputName)) — вместо mc %(Filename) в VS2019 должно быть mc %(FullPath). Имена производимых файлов для MC ($(InputName).h и $(InputName).rc) не сконвертировались вообще; в VS2019 они должны иметь вид %(Filename).h и %(Filename).rc.
  • Имена производимых файлов для Resource Compiler ($(IntDir)\$(InputName).res) также не сконвертировались; в VS2019 они должны иметь вид $(IntDir)\%(Filename).res.
  • <TargetName> нужно изменить со значения по умолчанию ($(ProjectName)) на vfd для проекта vfdlib и vfdwin для проекта vfdwin, иначе они пытаются собрать файлы lib.dll и gui.exe.
  • Чтобы скомпилировать VFD без zlib, нужно не только добавить к определениям VFD_NO_ZLIB, но и убрать #include "zlib.h" под #ifndef VFD_NO_ZLIB — автор об этом почему-то забыл; и нужно убрать zlibstat.lib из <AdditionalDependencies>.

После этих исправлений успешно собираются 32-битные версии vfd.dll и vfdwin.exe; но чтобы собрать 64-битные версии, нужно потрудиться ещё.

Адаптация для x64


Во-первых, сам код несовместим с x64, и в нём нужно заменить
  • возвращаемый тип всех DlgProc с BOOL на INT_PTR;
  • все вызовы GetWindowLong(GWL_USERDATA) на GetWindowLongPtr(GWLP_USERDATA) и аналогично для SetWindowLong и для DWL_MSGRESULT и DWL_USER.

Во-вторых, в настройках сконвертированного проекта не используется $(Platform), потому что во времена VC6 платформа могла быть только одной; и поэтому 32-битные и 64-битные файлы пытаются собраться в одни и те же каталоги. Чтобы их развести, надо исправить на $(IntDir) значения <AssemblerListingLocation>, <PrecompiledHeaderOutputFile>, <ObjectFileName>, <ProgramDataBaseFileName>; <OutputFile> для линкера исправить на $(TargetPath); и удалить бесполезные <AdditionalLibraryDirectories>, вручную добавлявшую зависимость между проектами, и <PostBuildEvent>, вручную копировавшие скомпилированные файлы в целевой каталог.

В-третьих, vfdwin активно сопротивляется попытке запуска на 64-битной Windows, наравне с попыткой запуска на Windows 95/98/Me. Чтобы это пресечь, надо удалить функцию VfdIsValidPlatform() и все её упоминания.

Загрузка драйвера


У меня под рукой нет Windows DDK, так что я взял 64-битный vfd.sys, скомпилированный неким critical0, и попросил dartraiden подписать его «древне-китайским способом». Такой драйвер успешно загружается и работает, если vfdwin запущена с правами администратора; чтобы это происходило всегда, в её опции линковки нужно добавить <UACExecutionLevel>RequireAdministrator.

Другой энтузиаст, Igor Levicki, посвятил целый блогпост компиляции vfd.sys под x64, и утверждает, что его версия vfd.sys лучше, чем у critical0; но она подписана самодельным сертификатом, и не загружается без дополнительных телодвижений. Кроме самодельного сертификата, честолюбивый Igor Levicki добавил в файл драйвера упоминание себя и своего блога; critical0 такой ерундой не занимался.

Использование


Кроме перечисленных изменений, я лишь заменил в окне About давно мёртвый URL на github.com/tyomitch/vfd, и исправил один баг в оболочке, заметный только при отладочной компиляции: функция VfdGetLocalLink передаёт параметр типа CHAR в isalpha() и сваливается на строке _ASSERTE(c >= -1 && c <= 255); в стандартной библиотеке. Как объясняли в недавнем хабрапосте, поведение isalpha() не определено для отрицательных чисел, а CHAR в Windows как раз знаковый. Судя по тому, что при компиляции выдаётся 141 предупреждение, таких багов в коде может быть ещё немало; так что мне будет чем занять свободные вечера.

Готовые бинарники лежат в github.com/tyomitch/vfd/tree/master/x64/Debug

Похожие публикации

Средняя зарплата в IT

113 000 ₽/мес.
Средняя зарплата по всем IT-специализациям на основании 10 037 анкет, за 2-ое пол. 2020 года Узнать свою зарплату
Реклама
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее

Комментарии 27

    +1
    Эпичненько. Нарядная семейная галерея Windows.
    Предложу следующий объект портирования — Unisata. Используется в ReactOS, возможно, является одним из её якорей на 32-битной платформе. Автор заявлял планы выпуска 64-битной версии, но видимо пока не до неё.
      +2
      У нас uniata работает в 64-битной сборке ReactOS, хотя интенсивно не тестировался.
      Изменений потребовалось не так уж и много: github.com/reactos/reactos/commits/master/drivers/storage/ide/uniata
        0
        Отличная новость, спасибо. И да, конечно же UniATA.
          +1
          Я правильно понимаю, что для 64-битной сборки было достаточно изменить две строчки?
            +1

            Надо ещё что-то в config.h поменять. Проще всего поискать в репозитории по макросу __REACTOS__

        +3
        А что за древне-китайский способ такой?
            +4
            Подробностей не увидел. Хм, тянет на целую статейку
              +1
              Лучше без статеек. Ядро принимает истёкшие и отозванные сертификаты, вот и весь трюк. Поскольку нет информации, почему оно себя так ведёт, лучше слишком активно эту информацию не выпячивать в интернетах. Есть опасения, что если применение станет слишком широко распространённым, то MS может прикрыть эту дырочку в заборе.
                +1

                Так уже. Из того, что я нагуглил, много малвари этот трюк использует.

                  +1
                  Всё равно. Одно дело малварь, которую с одной стороны сами распространители стараются не афишировать, а внедрять втихую, а с другой — которую антивирусы регулярно отлавливают (в простейшем случае детектом по тем самым сертификатам). Другое дело, когда на каждом углу для всех чайников будут развесистые инструкции по скачиванию пакета и проведению нужых манипуляций для установки произвольного драйвера (включая отрубание антивируса). В такой ситуации MS может и зашевелиться, как в своё время внедрила UAC из-за того, что все сидели под админом.
                  +2
                  лучше слишком активно эту информацию не выпячивать в интернетах

                  Куда уж больше выпячивать, когда её включают в readme к софту?
                  github.com/AxtMueller/Windows-Kernel-Explorer#about-digital-signature-and-negative-comment-from-anti-virus-software
                    +2
                    Там, всё же, без конкретных инструкций и утилит.
            +4
            А чем не устраивает ImDisk Virtual Disk Driver например?
              +5

              Старые студийные проекты порой проще пересоздать, чем конвертировать и править. Особенно если файлов немного.

                +1

                А что мешает просто создать образ дискеты и его подсунуть виртуалке в виде флоппика?

                  +2
                  Когда нужно постоянно таскать файлы туда-сюда, через образ это делать неудобно.
                  +1
                  Есть вариант типа:
                  1. Выключить компьютер.
                  2. Вынуть из него диск.
                  3. Переставить диск в другой компьютер как второй.
                  4. Залить на диск нужные файлы, забрать с диска нужные файлы.
                  5. Вернуть диск обратно.
                  Всё это можно сделать на физическом компьютере. Почему бы не делать то же самое на виртуальном компьютере?

                  Ладно, допустим, таскать диск не нравится. Но что мешает установить на компьютер с DOS что-то типа NetWare Lite или аналогичную сетевую программу? Клиент Novell NetWare — есть и для 16-битных Windows. В принципе, можно и MS-сеть поставить — правда, она кушает память в неимоверном количестве.
                    0
                    EZ NOS — http/ftp/smtp сервер для DOS, exeшник занимает 300 КБ, оперативки ест 300 КБ, есть выход в DOS с оставлением NOS резидентным.
                      0
                      Это с драйверами NIC, или их нужно отдельно загружать?
                        0
                        Любой пакетный драйвер. В моём экземпляре уже есть 3с509, но возможно его туда добавили позже.
                          0
                          Сейчас заглянул, в дополнение к eznos.exe присутствует даже ez8086.exe!
                          0
                          Правильно всё-таки EZNOS, основан на JNOS (есть статья по настройке).
                        +1
                        PVS studio: github.com/tyomitch/vfd/issues/1
                        Total Warnings (GA): 40
                        Total Warnings (OP): 3
                        Total Warnings (64): 17
                          0

                          а бинари в репе гита хранить нынче уже не возбраняется?

                            +2

                            Технически никогда вроде не возбранялось. Но по хорошему этому место конечно в релизах.

                            0
                            Автор однозначно выразил одобрение переиспользованию его кода, поместив его под лицензией GPL. Просто сопровождайте свой форк, текст лицензии вы приложили, исходники есть. Формального какого-то прямо согласия от автора не нужно, правила хорошего тона вы уже соблюли, попытавшись связаться с автором.

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

                            Самое читаемое