Это могла бы быть рождественская история со счастливым концом, но он не такой.

В канун рождества 2018 года заметил в списке проверенных приложений для ReactOS установщик .NET 4.0 и был приятно удивлён, что он успешно устанавливается и приложения запускаются. Но так как 4.0 давно не актуален меня посетила безумная идея — а что будет если попытаться установить версию 4.5?

Установщик сразу заявил что версия ОС не подходит. Запуск в режиме совместимости так же определялся им и устанавливаться отказался. Дела, всё закончилось не начавшись…

Не совместимость с ОС

Да сейчас версию поменяю и все заработает!


ReactOS разрабатывается как аналог Windows 2003 и версию он сообщает как 5.2. Для установки требуется как минимум 6.0, но тогда я решил что целиться лучше сразу на Windows 7 и стал искать как менять версию на 6.1. В коде по словам version/MajorVersion/MinorVersion нашлось несколько мест по всей системе, даже там где не ожидаешь. Заменив все пары 5.2 на 6.1 результат был нулевой — не стартовал даже установщик ОС. Дальнейший поиск вывел на freeldr и ntldr в boot — в 4 местах надо было заменить _WIN32_WINNT_WS03 на _WIN32_WINNT_WIN7. ОС установилась и сообщает нам что это 6.1. Отлично?! Нет. Почему-то с такой заменой ничего толком не устанавливается — ни VirtualBox Guest Additions, ни Firefox, ни .NET 4.0 и даже проводник падает через раз. Окей, значит надо создать ISO со всем необходимым и подключить его к виртуалке. Слава байтам, привод ещё работает и снова стартуем установщик с него. Ура! Он хотя бы стартует, но жалуется на отсутствие неких компонентов ОС:

Предупреждения установщика

Первый это сервис автоматических обновлений, второй — Trusted Installer. Ничего подобного у нас нет — действительно, зачем в ReactOS обновления Windows, а Trusted Installer не может быть по определению ибо он появился вместе с Windows 7. Так же в логе нашлась строка, что отсутствует некий wusa.exe. Ок, создаём заглушки для wusa.exe и wuauserv.dll для сервиса обновлений PR 355. Trusted Installer просто скопировал из Windows 7 32bit вместе с ключами реестра. Теперь установщик определяет наличие всего необходимого и остаётся лишь скрепить договор капелькой крови.

Процесс верификации файлов проходит успешно и стартует установка. Сразу получаем сообщение, что не хватает функции LCMapStringEx в модуле kernel32.

LCMapStringEx

Ок, ищу функцию в коде и, вы удивитесь, она есть но почему-то не добавлена в экспорт-лист (spec-файлы рядом с CMakeLists.txt в корне каждой DLL). Сборка/Установка/Запуск и опять подобная ошибка. Что же, сценарий известен. После повторения этой процедуры 5-10 раз от прощёлкивания Enter-ом установщика нагугливается, что у ОС есть режим unattend-установки. Для этого нужно в файле boot\bootdata\bootcd\unattend.inf включить UnattendSetupEnabled = yes. Супер, сани едут сами! Едут так быстро, что за чаем не успеваешь сходить — минуты две вся установка.

Настройки в unattend.inf
Там же можно поменять папку установки с ReactOS на Windows или Bolgenos (а может и GreenteaOS? :) ), разрешение графического режима, включить установку темы и ещё пару моментов

Так как ReactOS пишется как 2003, то код для 6.0+ никто особо не поддерживает. Такие места закрыты условиями #if _WIN32_WINNT >= 0x600, а то и вовсе #if 0 и их приходится приводить в рабочий вид. Недостающую функцию (хотя код её есть @$&^%!) добавить в экспорт (SleepConditionVariableCS требует RtlSleepConditionVariableCS) или где-то в SDK-заголовках разблокировать структуры/поля. Ещё более странный костыль с ntdll, kernel32 и advapi32 — для них зачем-то созданы дополнения в виде ntdll_vista, kernel32_vista и advapi32_vista в каждой из которых максимум 10-15 процедур, при этом в kernel32 есть целых два файла vista.c. Лебедь, рак и щука, не иначе, принимали такие решения. Сейчас определённости так же нет — при выкладке ПРа на гитхабе один просит вынести код в *_vista-либу, второй пишет что достаточно закрыть экспорт условием -version=0x600+ в spec-файле. Больше всего тут удивляет то, что все такие функции это новое API и вполне могут мирно сосуществовать с основным кодом, непонятно зачем городить такой огород.

Продолжались эти попытки на протяжении пары месяцев, но в итоге всё остановилось на том, что установщик зависал в середине процесса ни ругаясь, ни падая.

Быть, а не казаться


Летом решил вернуться к снаряду. Всё-таки столько времени потрачено, а результат нулевой. На этот раз решил делать всё иначе — раз при подмене сообщаемой версии с 5.2 на 6.1 всё работает вкривь и вкось, то надо менять версию совсем с другой стороны — попытаться собрать ReactOS полностью в режиме NT6.

Для этого надо в корневом CMakeLists.txt заменить следующие условия 0x502 на 0x600. Да, тут уже не до жиру, хотя бы 6.0 получить на выходе.

    # Version Options
    add_definitions(-DWINVER=0x502
                    -D_WIN32_IE=0x600
                    -D_WIN32_WINNT=0x502
                    -D_WIN32_WINDOWS=0x502
                    -D_SETUPAPI_VER=0x502)


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

#if (_WIN32_WINNT >= 0x600)
NTSTATUS
RxConstructSrvCall(
    _In_ PRX_CONTEXT RxContext,
    _In_ PIRP Irp,
    _In_ PSRV_CALL SrvCall,
    _Out_ PLOCK_HOLDING_STATE LockHoldingState);
#else
NTSTATUS
RxConstructSrvCall(
    _In_ PRX_CONTEXT RxContext,
    _In_ PSRV_CALL SrvCall,
    _Out_ PLOCK_HOLDING_STATE LockHoldingState);
#endif         

Ошибки сборки сыпались как из рога изобилия, самые простые из которых были в том что в CMake-файлах некоторых dll WINVER и _WIN32_WINNT явно переназначались на иные значения, например 0x602. При этом в ReactOS полно dll, у которых и сейчас WINVER переопределён с 0х502 на 0х600. Нашлось и несколько настоящих багов #356 #359 #747 #814 #815.

Длилось это так же месяц-два и в итоге со всеми костылями образ собрался, но вот установщик не подавал признаков жизни совсем. Помучавшись немного ещё запал пропал

Логика не железная


Грядёт новое рождество, а .NET 4.5 не даёт покоя. Вновь возвращаюсь к первому варианту, повторяются все правки, но с некоторыми изменениями. Если раньше вместо недостающих функций (для которых нет кода в ОС) делал просто заглушки, то теперь решил поискать их в коде Wine и, о чудо, там они были. Перенести, адаптировать под ReactOS, к следующей #1045. Где-то вместо заглушки можно и настоящего кода написать :) #1046. С такими правками установщик работал уже по-бодрее и даже завершался «успешно», но в отличие установщика .NET 4.0 не предлагал выполнить перезагрузку после установки — я списал на то, что все таки софт для нового поколения ОС и нет нужды перезагружаться каждый раз (ха ха, святая наивность). При попытке запустить helloWorld-приложение на экране не происходило ничего, в task manager тоже не успевал заметить какую-то активность.

Небольшое отступление по установщику
в самом начале пути, что бы не ждать каждый раз старт установщика, я распаковал его в папку и щёлкал setup.exe вручную. Запускать нужно с аргументом /x86 для чего создал к нему ярлык

Немного позже решил покопаться в ресурсах установщика, где нашел текст сообщений об ошибках и ВОТ СЮРПРИЗ — все ограничения указаны в файле ParameterInfo.xml! Достаточно было закомментировать StopBlockers-условие IsInOSCompatibilityMode и всё стартует без проблем. Убираю правки, которые меняют версию ОС с 5.2 на 6.0, включаю в ярлыке к setup-у режим совместимости с Vista (так он не ожидает наличие Trusted Installer) и добавив ещё немного функций установщик завершался так же «успешно». Однако если сперва установить 4.0 и потом запустить установщик 4.5, то процесс завершился уже с просьбой перезагрузиться! Победа!? Нет. Я же говорил что это сказ без хэппи-энда. При попытке запустить HelloWorld результат немного отличается, но не сильно — процесс занимает 11-12МБ памяти и, повисев секунд 20, завершается. Запуск в режиме совместимости не помогает (всё-таки CLR-runtime запускается в каждом процессе отдельно, а не одна общесистемная среда, которая стартует вместе с ОС с версией ОС 5.2).
В логе видим вызовы на определение версии:

Проверка версии

Добавил в RtlVerifyVersionInfo хак, что если запрашивается версия 6.*, то подменить версию ОС на 6.0. Отмеченные стрелкой строки ушли, но результат тот же.

Не хэппи-энд.

Заключение


Возможно до успеха осталось совсем немного и вы, вдохновились этим рассказом, готовы подхватить флаг и закончить начатое скачав код ReactOS и собрав её? Не так быстро. Почти по всем ПР на сделанные изменения при их выкладке сперва идёт какое-то обсуждение, но потом они висят без внимания основных разрабов ОС.

Для того что бы повторить описанное надо на мастер-ветку накатить ПРы по ссылкам в тексте, разблокировать пачку функций в spec-файлах (заменить версию в условии -version на 0x500+) и несколько 0x600-условий в заголовках

Список изменений для .NET 4.5
Помимо ПРов надо поправить немного winbase.h wincon.h и открыть функции из списка ниже
advapi32

  • EventWrite (stub)
  • EventRegister (stub)
  • EventUnregister (stub)
  • RegLoadMUIStringA
  • RegLoadMUIStringW


msvcrt
  • _except_handler4_common


kernel32
  • AcquireSRWLockExclusive
  • AcquireSRWLockShared
  • CloseThreadpool
  • CloseThreadpoolCleanupGroup
  • CloseThreadpoolCleanupGroupMembers
  • CloseThreadpoolIo
  • CloseThreadpoolTimer
  • CloseThreadpoolWait
  • CloseThreadpoolWork
  • SetThreadpoolTimer
  • SetThreadpoolWait
  • CompareStringEx
  • CreateSemaphoreExA (stub)
  • CreateSemaphoreExW (stub)
  • CreateThreadpool
  • CreateThreadpoolCleanupGroup
  • CreateThreadpoolIo
  • CreateThreadpoolTimer
  • CreateThreadpoolWait
  • CreateThreadpoolWork
  • EnumCalendarInfoExEx
  • EnumDateFormatsExEx
  • EnumSystemLocalesEx
  • EnumTimeFormatsExEx
  • FlushProcessWriteBuffers(stub)
  • GetCalendarInfoEx
  • GetDateFormatEx
  • GetLocaleInfoEx
  • IsValidLocaleName (stub)
  • GetNLSVersionEx (stub)
  • GetNumberFormatEx
  • GetTickCount64
  • GetTimeFormatEx
  • GetUserDefaultLocaleName
  • LCMapStringEx
  • InitOnceExecuteOnce
  • InitializeCriticalSectionEx
  • InitializeSRWLock
  • ReleaseSRWLockExclusive
  • ReleaseSRWLockShared
  • WerSetFlags (stub)


Некогда собирать, давай сюда сборку!


Если вы следите на развитием ReactOS и пробуете установить свежее приложение, то наверняка сталкивались с тем, что не хватает каких-то функций либо интересный/полезный ПР висит бесконечно. Мне это тоже знакомо и потому решил регулярно составлять сборку ОС с недостающими кусками и ПРами (хочу держать график еженедельно или раз в две недели). Попробуйте эту сборку, возможно она будет полезна! Пишите если столкнётесь с очередной отсутствующей функцией — высока вероятность что она уже лежит в коде ReactOS или есть в Wine. USB-драйвера в ней пока нет.

Скачать можно здесь

С новым годом и стабильного ReactOS-а!

Комментарии (38)


  1. vasyan
    04.01.2019 13:56
    +2

    Возможно до успеха осталось совсем немного и вы, вдохновились этим рассказом, готовы подхватить флаг

    И начать контрибьютить в wine


    1. Getequ Автор
      04.01.2019 15:20

      Нового кода написано минимальное количество, в основном как раз наоборот перетаскивал из Wine. А заглушка для wusa в Wine уже есть своя


  1. skymal4ik
    04.01.2019 14:14

    Круто, что проект живёт и развивается, пусть и немного медленнее чем хотелось бы!

    А из сообщества есть кто-то, кто пользуется ReactOS?
    Если есть, то расскажите почему ReactOS, и для каких задач используете? Мне вправду интересно :)

    Сам пару лет назад пытался завести специфичную программу бухгалтерии на б/у сервере, чтобы не покупать лицензию. Но увы, требуемая СУБД не завелась, поэтому нашёл системник с лицензией win 2003 server.


    1. HerrDirektor
      04.01.2019 14:51

      Я хотел на древний ноут поставить ее, но увы, не завелась :(
      Теперь периодически ставлю свежие билды на виртуалку, на этом пока все.
      Тем не менее, какой-никакой прогресс наблюдается, надеюсь, что доживу до финального билда :D

      Автору — всяческих благ в начинаниях, ну и плюсик в карму.


      1. Getequ Автор
        04.01.2019 16:39

        С ноутом у меня тоже была неудача, успешно поставилось на мать гигабайтовую с G965-чипсетом, даже USB-мышка работала. Потом это же хард подключал к матерям на сокет 370 и слот 1 — тоже загрузилось
        image


        1. HerrDirektor
          04.01.2019 16:46

          Интересно… Где-то у меня валяется древний сервак Сименс на P1 75Мгц с 32Мб RAM, нужно проверить, заведется ли там? NT4 на нем отлично себя чувствовала, а вот Win2k не помню, ставил или нет.


          1. Getequ Автор
            04.01.2019 17:00

            Вряд ли, надо как минимум 96МБ для реактоса, хотя может предустановленная стартанёт


    1. Merkat0r
      04.01.2019 16:37
      +1

      Эх… слишком медленно…

      image

      imho Маск быстрее на марсе колонию создаст, чем stable выйдет)))


    1. seven_hh
      04.01.2019 21:39

      Ставли reactos в виртуалку чтобы запустить игру дюны и пройти все уровни как это я делал лет 20 назад. Примечательно что ОС или игра зависла только один раз.


  1. Nagg
    04.01.2019 14:45

    (упс, мимо)


  1. varanio
    04.01.2019 16:40
    +12

    Вот бы статью типа "я использовал reactos для таких-то целей и сэкономил 100500 денег."


    А то читать про развитие ОС, которая никак не может догнать древнюю (уже никому не нужную) версию винды, начинает утомлять: не ясен смысл всего этого. Я вполне допускаю, что он есть, но я так и не понял его


    1. alan008
      04.01.2019 18:00
      +2

      Вероятно, во времена начала разработки РеактОС не предполагалось, что приложения будут обновляться каждый день, что многие API будут переписываться по 20 раз и вообще что значительная часть приложений уйдёт в веб. Цель-то была "запускать хорошие проверенные приложения на бесплатной ОС, совместимой с виндой", но когда винда сама превратилась почти что в SaaS, о чём вообще может идти речь в плане бинарной соаместимомти. Хорошие "прошлогодние" приложения уже не считаются хорошими.


    1. vasyan
      04.01.2019 20:23
      -1

      Теоретически reactos должна помочь работать с древним железом и помочь преодолеть санкции наших зарубежных партнёров.
      Вполне реальный сценарий, что кто-то из ростеха заметит эту ОС и ввалит в проект денег, тогда и релизы пойдут.


      1. geisha
        04.01.2019 21:01
        +2

        Линукс вам поможет работать с древним железом, а с санкциями ваших зарубежных партнеров бороться бесполезно, ибо корень проблем в другом. Реакт вполне имеет право на существование, но это проект вроде интернет-архива и я не думаю, что у него в принципе возможна широкая аудитория. А если кто-то из Ростеха ввалит в проект денег, то получится болгенОС с нескучными обоями и вайном по первой ссылке из гугла.


        1. seven_hh
          04.01.2019 21:45

          Линукс линуксу врознь, некоторые ОС плохо работают или вообще перестают работать со старым железом, как и с новым ещё не всё поддерживают. Здесь больше вопрос в том что это открытый исходный код и теоретически, человек с опытом может запустить старое железо. Но думаю компаниям типа Microsoft проще сделайть своей ОС поддержку старого железа чем одиночкам.


    1. seven_hh
      04.01.2019 21:36

      Я раньше тоже думал что винда дорогая и бедная компания не может себе позволить купить её на свои 10 компьютеров. Но когда посчитаешь сколько тебе денег за месяц ЗП оплачивают, то понимаешь что проще на месяц сотрудика уволить и купить ОС с лайфтайм лицензией на все компьютеры. Что она уже и так сделала, но все равно не собирается покупать. Ладно есть алтернативы, посидим немного на Linux. А вот платить за переодические платежи за софт (ежемесячные или годовые) мой мозг не понимает и упорно сопротивляется (кроме донейшен), но похоже что весь мир так живет и возможно это правильно, ведь все пополняют мобильный телефон.

      Поэтому да, мой путь использования reactos это понять что винду нужно покупать и на этом я сэкономлю 100 или 500 денег.


    1. mkshma
      04.01.2019 21:58

      Вот бы статью типа «я использовал reactos для таких-то целей и сэкономил 100500 денег.»

      Она даже для тестового использования-то не годна, а вы говорите для «целей». А вроде как 20 лет прошло.


      1. Jeditobe
        04.01.2019 02:14

        Спорное утверждение.


  1. id_potassium_chloride
    04.01.2019 17:59
    -7

    Парень, ты классно провёл время, но ты бы это… Может, лучше погулять сходил бы (лучше с девушкой/женой) или съездил бы куда отдохнуть немного (или как там обычно негики отдыхают?)…


    1. valis
      04.01.2019 18:51
      +1

      Ну, каждый по своему досуг проводит. Я никого не ругаю за покупку зеркалок с обвеской за 10к+ баксов, которые ничего не зарабатывают, коллекционирование марок и прочих хобби.
      Кейсов применения данной системы я не понимал ни когда о ней в первые услышал (лет 6 назад), ни тем более сейчас
      Но то что делают ребята это круто — просто круто!


      1. id_potassium_chloride
        04.01.2019 18:59

        Да, я понимаю и не осуждаю автора. Более того, своим замечанием в скобках я как бы намекаю, что я сам из примерно таких же :)

        Разработчики ReactOS круты. (Если не ошибаюсь, их сейчас по всему миру около 30 человек, но они по-прежнему что-то делают по проекту.) И автор статьи тоже крут. Судя по минусу, я никогда не смогу в юмор :(


  1. vsb
    04.01.2019 19:34

    А нельзя этот дотнет просто папкой скопировать? Я с Java работаю. На Windows XP последние версии Java 8 официально не поддерживаются и инсталлер даже не запускается. Однако если установить Java на той же 10-ке и потом просто скопировать папку с установленной Java на XP, всё прекрасно работает. По сути вы заморачиваетесь с тем, чтобы запустить инсталлер, но это же просто программка для копирования файлов и правки каких-нибудь веток в реестре, тут главное чтобы сам .NET работал.


    1. Getequ Автор
      04.01.2019 19:54

      У меня цель была в том, что бы установщик в ОС выполнил все нужные операции самостоятельно.
      Хотя надо попробовать, если сработает и приложение стартанёт, то хотя бы можно будет исключить, что проблема с самом .net-e


  1. maxbl4
    04.01.2019 19:59

    А может попробовать с dotnet core? Во первых, он гораздо более современный, чем 4.5 и если заработает, позволит запускать полезные современные программы. Во вторых, dotnet core кроссплатформенный и изначально должен быть слабее завязан на windows, в третьих он не требует установки, просто распаковать архив и запускать бинарник, так что отладка должна быть гораздо легче


    1. alexr64
      04.01.2019 21:14

      Ценность полного фреймворка в наличии win-forms, а это уже вполне юзабельный гуй. Но ради интереса, можно и задеплоить self-hosted hello world на корке, да.


      1. QtRoS
        04.01.2019 11:52
        -1

        Полные и красивые окошки есть в Qt, ещё и кроссплатформ. Если не изменяет память, даже на win98 запускались в 12 году, сейчас не знаю, но XP и 2003 наверняка ещё поддерживаются.


  1. maxbl4
    04.01.2019 21:18

    Core Alpha 3.0 умеет winforms и wpf


    1. Andriy1218
      04.01.2019 16:38

      Только как я понимаю, сами winforms и wpf не кроссплатформенные. Wpf наверняка не запустится на react, а вот .net core 3.0 + winforms можно попробовать.


      1. maxbl4
        04.01.2019 16:59

        Да, эти компоненты только под windows.
        Есть ещё project avalon — кроссплатформенный аналог wpf, но я не знаю в каком он состоянии и он походит для новой разработки, готовых программ на нем наверно нет


        1. Andriy1218
          04.01.2019 21:36

          Avalonia хоть и активно развивается, но все равно медленно. Пока что доступны только самые базовые элементы. Есть еще несколько кроссплатформенных GUI-фреймворков, например Eto или XWT. Но все эти фреймворки конечно не дотягивают до winforms.


  1. Enmar
    04.01.2019 22:27

    Интересно, а как дела с Mono?


  1. nefedr
    04.01.2019 07:32
    -3

    Вся конструкция, называемая reactos, делалась для миграции из винды в линукс, и исключительно для тех, кто не очень въезжает в терминальные команды. Если кто не помнит, в 1988 состоялся так называемый мировой финансовый кризис, и некие ребятки и девчатки решили, что юзеры уже не осилят 130$ за виндовс 2000. И пошли твердыми, но криво поставленными шагами навстречу светлому будущему: переходу на линукс во всемирном масштабе. Получилось из этого то же, что и у Троцкого со Свердловым и Лениным в масштабе Российской Империи. Кризис миновал, денег у людей на ОС хватает, линукс развивается, и очень даже неплохо. А вот reactos завис. По моему-абсолютно не пригодная к практической работе система. Но уж ежели есть желание у кого покипятить собственный мозг, может быть попробовать поставить все ж кроссовер? У меня стоит он на ghostbsd и чудным образом запускает клиент-банки, 1с, и всякую железнодорожную софтину. Я не против мазохизма, но стоит ли оно того?


  1. Getequ Автор
    04.01.2019 07:51
    +1

    Кто-то на досуге паяет, мастерит 3д-принтер, пишет абстрактную ОС, ну а кто-то вполне конкретную с самым распространённым API в мире


  1. box4
    04.01.2019 10:33

    Может быть направить эту энергию на развитие линукса? Или на развитие diskcryptor.


  1. Boroda1
    04.01.2019 11:48

    Насколько я знаю, есть товарищ Святослав Гонтарь, который занимается One Core Api, а именно допиливает функционал NT6+ в NT5 системы. Причём довольно успешно, потому как на его Windows Server 2003 уже запускается куча NT6+ приложений. Возможно, стоит глянуть в эту сторону, потому как эта работа уже, вероятно, им сделана.


    1. Naglec
      04.01.2019 12:18
      +1

      Но зачем? В чем смысл?


      1. Boroda1
        04.01.2019 12:29
        -1

        Конкретно в данном контексте — это позволит сделать ReactOS совместимой с NT6+, а не с NT5, как задумывалось изначально.


        1. Naglec
          04.01.2019 12:52
          +2

          Очевидно, вопрос был про One Core Api. Нахрена оно надо