The tale of how .NET 4.5 on ReactOS was put

It could have been a Christmas story with a happy ending, but it’s not exactly that.

On Christmas Eve 2018, the .NET 4.0 installer noticed in the list of proven applications for ReactOS and was pleasantly surprised that it was successfully installed and applications started. But since 4.0 has long been out of date I was visited by a crazy idea - what will happen if you try to install version 4.5?

The installer immediately stated that the OS version is not suitable. Running in compatibility mode was also determined by him and refused to be installed. Things are all over without starting ...

Not compatible with OS

Yes, now I will change the version and it will work!


ReactOS is developed as an analogue of Windows 2003 and the version it reports as 5.2. Installation requires at least 6.0, but then I decided to aim better at Windows 7 right away and began to look for how to change the version to 6.1. In the code according to version / MajorVersion / MinorVersion, there were several places throughout the system, even where you do not expect it. Replacing all pairs 5.2 with 6.1, the result was zero - even the OS installer did not start. Further search brought to freeldr and ntldr in boot - in 4 places it was necessary to replace _WIN32_WINNT_WS03 with _WIN32_WINNT_WIN7. The OS is installed and informs us that this is 6.1. Fine?! Not. For some reason, with such a replacement, nothing really is installed - neither VirtualBox Guest Additions, nor Firefox, nor .NET 4.0, and even the explorer crashes through time. Okay, so you need to create an ISO with everything you need and connect it to the virtual machine. Glory to the bytes the drive still works and again we start the installer from it. Hooray! He even starts, but complains about the absence of some OS components:

Installer Warnings

The first is the automatic updates service, the second is the Trusted Installer. We don’t have anything like it - really, why Windows updates in ReactOS, and Trusted Installer cannot be by definition because it appeared along with Windows 7. Also, there was a line in the log that there is no wusa.exe missing. Ok, we create stubs for wusa.exe and wuauserv.dll for PR 355 update service . Trusted Installer simply copied from Windows 7 32bit along with registry keys. Now the installer determines the presence of all necessary and it remains only to seal the contract a drop of blood.

The file verification process is successful and the installation starts. Immediately we receive a message that the LCMapStringEx function in the kernel32 module is missing.

LCMapStringEx

Ok, I am looking for a function in the code and, you will be surprised, it is there, but for some reason it is not added to the export list (the spec files next to CMakeLists.txt in the root of each DLL). Build / Install / Run and again a similar error. Well, the script is known. After repeating this procedure 5-10 times from clicking on the installer's installer, it swallows up, that the OS has an unattend-installation mode. To do this, in the file boot \ bootdata \ bootcd \ unattend.inf enable UnattendSetupEnabled = yes. Super sled ride yourself! They go so fast that you don’t have time to go for tea - the whole installation takes about two minutes.

Settings in unattend.inf
You can also change the installation folder from ReactOS to Windows or Bolgenos (and maybe GreenteaOS? :)), enable graphics mode, enable the installation of the theme and a couple more moments.

Since ReactOS is written as 2003, no one particularly supports the code for 6.0+. Such places are closed by the conditions #if _WIN32_WINNT> = 0x600, or even #if 0, and they have to be brought into working view. The missing function (although its code is @ $ & ^%!) Is added to the export (SleepConditionVariableCS requires RtlSleepConditionVariableCS) or unlock structures / fields somewhere in the SDK headers. An even more strange crutch with ntdll, kernel32 and advapi32 - for some reason, additions were created for them in the form of ntdll_vista, kernel32_vista and advapi32_vista in each of which a maximum of 10-15 procedures, while in kernel32 there are as many as two vista.c files. Swan, cancer and pike, not otherwise, made such decisions. Now there is no certainty either - when displaying PRA on a githabe, one asks to bring the code to * _vista-libu, the second writes that it is enough to close the export with the condition -version = 0x600 + in the spec-file. What is most surprising here is that all such functions are a new API and may well coexist peacefully with the main code, it is unclear why to make such a garden.

These attempts continued for a couple of months, but in the end everything stopped at the fact that the installer was hanging in the middle of the process, neither cursing nor falling.

Be, not seem to be


In the summer I decided to return to the projectile. Still, so much time spent, and the result is zero. This time I decided to do everything differently - if you replace the reported version from 5.2 to 6.1, everything works at random, then you need to change the version from the other side - try to build ReactOS completely in NT6 mode.

To do this, in the root CMakeLists.txt, replace the following conditions 0x502 with 0x600. Yes, there is no time for fat, at least 6.0 to get at the exit.

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


Expectations of success from this venture were initially so-so, although the idea as a whole is correct.
The problem is that in the NT6 kernel, many functions have changed signatures, data structures differ in composition and field order.

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

Build errors fell as if from a cornucopia, the simplest of which were that in the CMake files of some dll WINVER and _WIN32_WINNT were explicitly reassigned to other values, for example, 0x602. In this case, ReactOS is full of dlls, in which even now WINVER is redefined from 0x502 to 0x600. There were some real bugs # 356 # 359 # 747 # 814 # 815 .

It lasted just a month or two, and as a result, the image gathered with all the crutches, but the installer showed no signs of life at all. Having tormented a little more sunk gone

The logic is not iron


New Christmas is coming, and .NET 4.5 does not give rest. I return to the first version again, all edits are repeated, but with some changes. If instead of missing functions (for which there is no code in the OS), I used to do just stubs, now I decided to look for them in the Wine code and, oh, a miracle, they were there. Transfer, adapt to ReactOS, to the next # 1045 . Somewhere instead of a stub you can write a real code :) # 1046. The installer worked with such revisions more vigorously and even ended “successfully”, but unlike the installer .NET 4.0 did not offer to perform a reboot after installation - I wrote off that all the same software for the new generation of OS and there is no need to reboot every time ( ha ha, holy naivety). When I tried to start the helloWorld application, nothing happened on the screen, I also did not have time to notice any activity in the task manager.

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

A little later, I decided to delve into the installer resources, where I found the text of error messages and HERE SURPRISE - all limitations are specified in the ParameterInfo.xml file! It was enough to comment out the StopBlockers-condition IsInOSCompatibilityMode and everything starts without problems. I remove the edits that change the OS version from 5.2 to 6.0, switch on the Vista compatibility mode in the shortcut to setup (this way he doesn’t expect the Trusted Installer) and adding a few more functions to the installer was also completed successfully. However, if you first install 4.0 and then run the installer 4.5, then the process has ended with a request to reboot! Victory!? Not. I told you that this is a tale without a happy ending. When you try to start HelloWorld, the result is slightly different, but not much - the process takes 11-12MB of memory and, hanging 20 seconds, ends.
In the log we see calls to determine the version:

Version check

Added a hack in the RtlVerifyVersionInfo, that if version 6 is requested, then replace the OS version with 6.0. The lines marked by the arrow are gone, but the result is the same.

Not happy ending.

Conclusion


Perhaps there is still quite a bit of success and you, inspired by this story, are ready to pick up the flag and finish the job by downloading the ReactOS code and compiling it? Not so fast. Almost all the PR for the changes made when they are laid out, first there is some discussion, but then they hang without the attention of the main OS developers.

In order to repeat what was described it is necessary to roll on the master branch of PYA by the links in the text, unblock a pack of functions in the spec-files (replace the version in the -version condition with 0x500 +) and several 0x600-conditions in the headers

Changelog for .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)


No time to collect, let's build here!


If you follow the development of ReactOS and try to install a fresh application, you probably have come across the fact that some functions are missing or that an interesting / useful PR hangs endlessly. This is also familiar to me, and so I decided to regularly compile the OS with the missing pieces and PRAMs (I want to keep the schedule weekly or every other week). Try this build, maybe it will be useful! Write if you encounter another missing function - the probability is high that it already lies in the ReactOS code or is in Wine. USB driver in it yet.

Download here.

Happy New Year and stable ReactOS!

PS Important update!A simple console application compiled under 4.0 or 4.5 that lists folders / files on the disk works fine. So cant somewhere with WinForms and WPF (hangs as WinForms-example), and not all CLR.
During the 4.5 installation, I noticed ngen.exe processes with the remove System.Windows.Forms or System.Dynamic, etc. argument. It seems to delete deleted, and the new assembly did not register normally

PPS SUPER important update! Installer 4.5 removes some assemblies from the GAC in the process of work, but it falls off somewhere and does not have time to copy new ones (\ Microsoft.NET \ assembly \ GAC_MSIL). As a result, there are 73 out of 115 assemblies. If you copy the System, System.Drawing, System.Windows.Forms and Accessibility assemblies there, the simple WinForms application starts!

PPPS It turned out to be a great moment - if you copy mscoree.dll from 4.0 into system32, the 4.5 installer doesn’t work to its fullest, but after rebooting the console and win-forms applications start.

Also popular now: