Remove CSRSS

From ReactOS Wiki
Jump to: navigation, search

"Remove" CSRSS

Introductory note: This is a rather radical suggestion that came from KJK::Hyperion from back in 2003, when ReactOS was at its beginnings. See these two ros-kernel mailing list messages: message 1 and message 2, for the original text. It is doubtful this would be considered. However, if someone were to develop this for an existing Windows install and demonstrate that it won't adversely affect driver or application compatibility, then it might be worthy of consideration. (Text extracted from the mailing list and put in form by PurpleGirl; annotations added by hbelusca).

"Get rid of the CSRSS monstrosity for good. Forget the NT-compatible design: it's half-baked and ultimately broken. It's a memory hog, it's inflexible, it duplicates kernel data structures for no good reason, and it's the single worst bottleneck of process startup time. Its sole presence makes running user-mode processes and threads from kernel mode (piece of cake on UNIX) a nightmare. Console handles not being valid handles is just unwise and introduces all sorts of limitations and baroque workarounds. If win32k.sys needs a process to map the shared data in read-write mode and run worker threads (the only good reason to have CSRSS still around), it can still fork the System process. CSRSS as a hard error handler is laughable: it just spams all desktops with the stupid stay-on-top message box we all know - even the MS-DOS hard error handler was friendlier than that. CSRSS as a debug proxy server is useless - LPC-based debugging is a thing of the past. Really, you can't do half efforts at a microkernel: it's a microkernel or it's not."

NOTE: Back in the days of Windows NT 3.1, 3.5 and 3.51, all the windowing subsystem was residing in user-mode and was implemented as a subsystem called "csrss.exe" and its associated DLL files (csrsrv.dll, basesrv.dll and what was the core windowing subsystem, winsrv.dll). This was in accordance to the vision of different subsystems for implementing different aspects (Win32, OS/2, etc...) on top of the NT operating system. Starting Windows NT 4 (and up), however, Microsoft splitted the windowing subsystem in a piece residing in user-mode (CSRSS + some bits in winsrv.dll) and put the big part in kernel-mode (win32k.sys). This split was introduced on performance grounds (according to standards at that time). But this led to some duplication of data structures between the user-mode component and the kernel-mode component of the windowing subsystem to ensure communication between them (in particular, structures describing the processes maintained by this subsystem).

"Instead of the csrss-style architecture, the consoles will become true devices. The console driver will still be just a bridge between client applications and a server, but this shouldn't be underestimated. The slave side requires a server process, because it's just better, and if said server process can be user-defined (plain impossible with CSRSS - if not for anything else, no way you could signal a console client from a console server running under a different account), it's even better. Using I/O for inter-process communication *may* be even less efficient than LPC, but there's the big advantage that I/O is exponentially easier to use in kernel-mode, and supporting a kernel-mode console server is vital (imagine the headless server scenario. A simple kernel-mode console server is efficient - cutting on all the fancy user-friendliness that a headless server rarely needs - and removes the need for win32k.sys, while still exposing a decently usable console). Console handles, as a side effect, will be true, full-fledged handles, with correct handle semantics. The RunAs command always opens a new console because console handles aren't true handles (see previous paragraph). True handles mean that, when switching from text-only mode to GUI, the text-mode console server could spawn a child process (the GUI console server) and hand over the ownership of the slave side to it by simply duplicating its handle - thus preserving all the consoles you opened in text mode. True handles mean you could attach to any console and write to it - message broadcasts in text mode anyone? If this sounds a bit like UNIX, then that's the point.

Preserving the old console control semantics (creating a dispatcher thread that goes through the list of registered handlers) won't be hard once you remove the requirement for threads to be registered with CSRSS: you just create the thread. End of the story. Threads created from outside kernel32.dll will lack the default exception handler, so what? If you're really interested in that, you write it by yourself - the default exception filter does all the magic, and it's a public function. The real point is that you can happily call Win32 functions (and - especially - write to consoles) with no special initialization steps. Let's not go into what unholy steps are to be taken on Windows to trick CSRSS into accepting a Win32 process that wasn't started, in turn, from a Win32 process (let's just say it involves a disassembler - in your code, not as a development tool - and a lot of testing). Really, ReactOS will be a much better place without CSRSS."

NOTE: I agree with the overall idea. A similar idea is also discussed by a blog contributor in this article "Why aren’t console windows themed on Windows XP? (The Old-New Thing)" by Raymond Chen, and was actually introduced starting Windows 7 (2008-2009), where the window consoles were moved out of CSRSS and were implemented inside a regular user-mode process "conhost.exe", and in Windows 8+ where the conhost.exe process was kept, and a console driver "condrv.sys" was introduced to manage the virtual/fake console handles and transform them into real handles to (kernel) objects, with correct handle semantics, security, et al.

"No CSRSS means that nothing must be started before you can start anything else. No CSRSS, nor SMSS: If I want the kernel to run a batch file at startup instead of SMSS, I should be able to - in fact, a boot-time script should be the *default*."

NOTE: If the author of these lines understood the matter, he would have understood that SMSS is to NT what the INIT process is to Linux. But, to my mind, having the kernel itself running a batch file just like that (actually it would have to call back a user-mode shell of course) would be a bit problematic in terms of security. But anyway.

"Boot time activities, such as loading the well known DLLs, creating the swap files, saving the crash dump to a file, etc. will be assigned to startup scripts and applications, to allow a better granularity of configuration."

NOTE: I agree on that with the author. The SMSS program could be made to actually start configuration scripts that perform these jobs, instead of "hardcoding" these configuration steps inside it. This would be some equivalent to an INIT (+ system-D or whatever...) on Linux.

"The whole concept of a "boot verification program" will be obsolete."

NOTE: It is on Windows, either, starting Windows 2003 (NOTE: This boot-verification program is used to notify the NT kernel that the system configuration settings in the currently-used SYSTEM registry hive are OK).

"You'll be able to decrypt the SAM with a custom procedure, instead of being limited to a measly three options (see SysKey), none of which sounds all that exciting (what if you want to use SHA-1 + AES? what if you want to use a smart card? etc.). Winlogon and the SCM will be two normal user-mode applications, with nothing really special about them: you'll be able to start and stop them at will, or kill them if they misbehave (all too common for such a complex beast as Winlogon) - or not run them at all."

NOTE: Discutable points...

"The setup program could even be a Win32 app! To whomever is currently developing it: imagine being able to debug USetup in Visual Studio (or your favorite debugger/IDE), instead of... whatever you're using now. You could use Format and Fdisk (maybe implementing a console server in USetup to better control them), instead of duplicating their features inside USetup, and the future transition to a GUI installer would be seamless."

NOTE: This is what we call nowadays the First_Stage_GUI_Setup, and can be trivially implemented using the same core functions that also make USetup work. NOTE: USetup is a native NT application, therefore using the really bare NT operating system, without referring to any "Windows/Win32" functionality. This has by the way nothing to do with our overall CSRSS discussion whatsoever.

"Phasing out CSRSS alone could be the single biggest step towards the mythical one-phase setup. This is currently feasible, yet will complicate setup design. Lack of CSRSS will make it easier."

NOTE: From the remarks made above, we understand that here the author, in the middle of his rant, mixes two unrelated stories together. Also, note that a "one-phase" setup is not really possible (and doesn't exist on Linux either to my knowledge), because the 1st-stage setup consists of a running system (from the installation LiveCD) that copies and preconfigures the system that is being installed, and then, the 2nd-stage, started after a machine reboot, is the system being installed that is now running and self-configures itself. It is only now that one can choose to have an operating system that can continue to run by itself without a final reboot (or with a reboot).

"Hard errors will be handled per-thread, with callback semantics, like they're meant to be (except those with an action of ShutdownSystem, that are meant to cause a controlled BSOD). The PEB has room for several callback pointers: it won't hurt to reserve one for hard errors, and an extra one called by win32k.sys to convert a thread into a GUI thread, that could be handled in user32.dll by, among other things, replacing the hard error handler with one that shows a message box (possibly thread-modal, certainly not broadcasted). For those unsure: yes, it has to be a callback - it's vital for out ntdll!Ki* symbols to strictly match those of Windows, because the awareness of the hidden, locked potential of the Native layer is growing, and it would be gratuitous to change well-known stuff "just because". Having few, predictable entry points from which execution can resume is good design, too: just look at all the pains the Valgrind team is going through to catch all signals, lacking Linux well-defined points at which execution resumes (not counting the NtContinue and NtSetContextThread anomalies, Windows has exactly four - namely, user-mode APC, callback, exception and system exception. Five, if we count LdrInitializeThunk in)."

NOTE: A hard error indeed comes from the kernel, and the pops-up through the user-mode, but it should be kept centralized, especially when it's a hard-error that was triggered by the kernel due to an operation originally started by a user-mode application, and (for whatever reason) also happens to completely hang. The argument presented by the author is discutable.

"CSRSS as a host for win32k.sys kernel-mode worker threads is useless. It's documented in "Inside Microsoft Windows 2000". Try to terminate CSRSS, just for fun: observe how the GUI freezes. Win32k.sys can either exploit the under-used System process (it typically has just less than 500 KBs of virtual memory), or fork it with PsCreateSystemProcess."

NOTE: CSRSS was actually needed back in the Windows NT <= 3.51 days. Since the move of most of the windowing subsystem in kernel-mode in Windows NT 4 it made the architecture awkward. I suspect they didn't want to re-architecture all the stuff at once due to time limits. Nowadays (starting Windows 7 actually), the CSRSS is now scarcely used: only for centralizing information about VDM (Virtual DOS Machines) running on x86-versions of Windows, the hard-error user-mode pop-ups, possibly some user-mode information concerning Terminal Services. All the rest is now in kernel-mode in win32k.sys and, concerning the console subsystem, was completely removed from CSRSS, starting Windows 7 and Windows 8+.

"CSRSS as a debugging proxy server is an outdated concept: Windows XP and later have abandoned the old LPC-based debugging API in favor of a more traditional object-oriented native API, so let's do exactly the same."

NOTE: Since our rewrite of our CSRSS code, this is also deprecated in our code.

"Removing CSRSS will give you backward *and* forward compatibility. "Forward" because you'll be able to use Windows applications in contexts where it used to be impossible. Moving the consoles to a driver just begs to be done, even if it's difficult, and it's the key to unlock a better Windows."

Yay ;-)