The Session Space
The other components of a logon session that Figure 1 shows include the Win32 kernel-mode subsystem (win32K.sys) and a display driver. A Terminal Server console session's display driver is a standard display driver a video card vendor supplies. The display driver provides an interface for the video card's capabilities and hardware so that Win32 can display graphics. Identical video drivers ship in standard versions of NT. A Win32K instance for a Terminal Server client connection cannot use the console's display but must instead send drawing orders to the client machine. Thus, Terminal Server provides a virtual display driver (tsharedd.dll) for nonconsole sessions. This virtual display driver appears to Win32K exactly like a real hardware video driver, but instead of writing to the video card's graphics memory, the virtual display driver writes into buffers that represent the client's display. Terminal Server's communications stack transmits the buffers to the clients.
Terminal Server's designers had two design choices for making the Win32K subsystem handle multiple logon sessions. The first choice was to have one instance of Win32K that knows about all logon sessions and maintains state information specific to each session (such as a list of windows, the windows' positions, cursor position, and all other data the standard version of NT's Win32K keeps track of for a graphical logon). This approach would require extensive modification to Win32K's internal data structures and control routines, because Microsoft wrote Win32K under the assumption that only one set of input devices and one output device exist.
The second design choice, which Citrix used with WinFrame and the Terminal Server design team used, was to create a new instance of Win32K for each logon session. The advantage of this design is that it requires minimal changes to Win32K, so Win32K still assumes there is one set of input devices and one output device. However, if you're familiar with NT's virtual memory architecture, you know that a problem had to be overcome before the second design choice would work.
The standard NT memory map, which Figure 2 shows, comprises one 4GB region divided into two 2GB parts (in NT 4.0, Enterprise Edition, you can opt to reconfigure this division to 3GB and 1GB). The lower 2GB portion contains application-specific mappings, and this portion changes to reflect the application currently executing on the CPU. The upper 2GB portion is fixed and contains the kernel-mode portions of NT, including device drivers, the hardware abstraction layer (HAL), the Kernel, and the Executive subsystems. The upper memory portion does not recognize multiple address spaces; however, supporting multiple instances of Win32K requires recognition of multiple address spaces.
To overcome this problem in the upper memory portion of NT's memory map, Terminal Server's memory management extends NT's basic model to support one region of memory in the kernel-mode half of the memory map. This region is called the Session Space, and it can switch among different mappings. The Session Space occupies a fixed 80MB range of the virtual memory map just above where the Kernel and other Executive subsystems reside, and NT places different instances of Win32K in this range. The RDP graphics driver also instantiates in this area. When Terminal Server creates a new session, Session Manager uses a new system call to direct the mapping of Win32K, the RDP display driver, and kernel-mode print drivers into the Session Space, as Figure 3 shows.
NT uses the same mapping mechanism in the Session Space that it uses to map applications in the user-mode part of virtual memory. NT initially marks the entire Session Space as invalid for a logon session. However, as Win32K and RDP execute in the Session Space, NT's Virtual Memory Manager retrieves the appropriate code or data from the files (in this example, win32k.sys or rdpdd.dll) and makes them valid. NT performs an important optimization: Memory mappings of the Session Spaces of all the logon sessions share the physical memory that stores the nonchanging parts of the code. This optimization mirrors the way NT shares, in the user part of virtual memory, code from system DLLs that map simultaneously into different processes. Section objects represent memory that two or more processes share. Terminal Server also virtualizes these objects, so only those processes that belong to the same session can share the memory.
The Rdpdd display driver is known as the RDP display driver. Win32K sends graphics output commands to the RDP display driver. Rdpdd processes the drawing command and sends it to the client via the RDP protocol stack (wdrdp.sys). Win32K instances associated with remote clients also receive mouse and keyboard input via Rdpdd, whereas the console instance of Win32K receives mouse and keyboard input from hardware on the console machine. Rdpdd's job is to pass output to, and obtain data from, communications endpoints for multiple client sessions. Terminal Server creates the endpoints in the wdrdp.sys driver, which implements, with the aid of rdpdd, the RDP protocol. Wdrdp sits on top of one or more Transport Stack Drivers (TDs). TDs talk to Terminal Server transport drivers that communicate using a particular networking protocol, such as TCP/IP, NetBEUI, or IPX/SPX. As I stated earlier, Terminal Server uses only the TCP/IP TDI driver (tdtcp.sys), but other drivers are present for MetaFrame to use (e.g., tdipx.sys, tdspx.sys, tdnetnb.sys).
The network-protocol layering I just described creates a stack of drivers called an RDP Listener Stack. A client first connects to Terminal Server through the RDP Listener Stack. Terminal Server then transfers the connection to a new instance of an RDP stack, and the Listener Stack returns to the listening state. When MetaFrame extensions load, an ICA protocol driver loads into the stack alongside Wdrdp. Termsrv also plays a role in communications with the client and the management of client connections by loading a WinStation Extension DLL. The extension DLL for the RDP protocol is wsxrdp.dll, and in this DLL the T.120 General Conferencing Control (GCC) component creates T.120 conferences and manages channels for those conferences with the aid of the T.120 Multipoint Communications Service (MCS) component. The GCC and MCS components are both part of the T.120 standard. MCS's conference-related management routines are in user mode in the Wsxrdp extension, whereas its critical data paths (such as writing data to a conference) are in kernel mode in wdrdp.sys. Terminal Server implements this split so that RDP's video display driver (rdpdd.dll) will have direct access to the RDP protocol stack (wdrdp.sys) without having to leave kernel mode. Switching between kernel mode and user mode would introduce a performance penalty.