Desktops and Windows
In the Windows operating system, the desktop one sees is made up of three things, a kernel mode desktop object, a user mode desktop window, and a desktop thread. While the desktop object can be considered almost mundane, the window and thread are somewhat special. In Windows, desktop windows are created differently from regular windows and all share a single desktop thread. This thread handles messages sent to the desktop window, though users will generally only see the desktop window if the explorer shell is not running. In ReactOS, desktop windows are treated as regular windows and have their own threads, resulting in some rather unpleasant consequences. This requires that each thread have a reference back to the desktop object, which is duplicated and handed to the thread by the function that does the actual desktop creation. This results in multiple copies of handles and references to the desktop object being scattered about and there is currently no mechanism in place to go and release the handles and references when an object is destroyed. Another problem rooted in ReactOS' handling of desktop window creation is even messier. When a window is created, the WND struct that represents its message window is allocated from the heap of the current desktop. When a new desktop window is created by an existing one, what happens is the WND struct is allocated on the old desktop's heap instead of the new desktop's heap. If the old desktop object were to go away, its heap is also reclaimed by the memory manager, which then might allocate it for use by something else. But the new desktop object is still around and relying on the WND struct allocated in that chunk of memory for receiving messages. The memory corruption that can occur basically brings down the new desktop and all the associated unpleasantness.
Giannis Adamopoulos has spent a good deal of time rewriting the NtUserCreateDesktop to remedy all of the problems described above. The biggest change was to consolidate all of the desktop threads into a single thread, which eliminated the need for duplicating handles and references for desktop windows for their respective threads. Theoretically he could have built in a mechanism in the teardown of the desktop threads in the old design to attempt to clean up lingering handles and references, but unifying the desktop threads into a single thread outright eliminates the need for the duplication of handles and references. Instead, the single desktop thread belongs to no one and a mechanism for giving it temporary access to handles and references of desktop objects on demand was set up. Giannis also did more special casing of the desktop window creation to ensure that memory allocations for a new desktop window goes to that new desktop's heap, thus fixing the potential memory corruption described above. The fix is regrettably not quite in yet due to an issue handling cursors in desktop windows. The cursor information needed happens to be in user32, whereas the code responsible for handling the cursor messages are in win32k. Once Giannis works out how to get the information he needs, a rather major architectural issue in ReactOS can be put to rest.
A question that people might ask is why bother with these cleanups, as creation and destruction of desktop windows does not intuitively seem to be a common occurrence. The first response would be, these are resource leaks and it really is good programming practice to squash such issues lest an unforeseen situation causes the problems to manifest in hard to debug ways. The second is that some applications do actually make use of multiple window stations, and hence desktop windows, for security purposes. For the curious, from a hierarchical point of view the running environment people see in Windows is organized first as sessions, which hold window stations, which themselves hold desktops. Terminal service connections each have their own session, for example, and Windows services run within a different window station than the user desktop on NT6. This isolation can be useful for sandboxing purposes and is utilized by programs that need to either protect a process from a regular user, or vice versa. As such, creation and destruction of desktop windows is not nearly as uncommon as one might assume.