Skip to content

Commit

Permalink
Final fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
TwoFX committed Feb 2, 2019
1 parent 81362c3 commit 44d2674
Showing 1 changed file with 110 additions and 111 deletions.
221 changes: 110 additions & 111 deletions report.tex
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
\usepackage{graphicx}
\usepackage{tikz}

\usepackage[margin=2cm]{geometry}
\usepackage[margin=1.88cm]{geometry}

\usepackage[
backend=biber,
Expand Down Expand Up @@ -158,9 +158,9 @@
Each window object is an instance of a given \textit{Window class}.
Window classes, while conceptually comparable, are not classes in
the object-oriented programming sense. Instead, windows classes are
registered to the kernel at runtime and can then be instantiated.
registered with the kernel at runtime and can then be instantiated.
Window classes determine the appearance and behavior of a Window.
Application developers create instanes of a window class
Application developers create instances of a window class
using the function
\texttt{CreateWindowEx}, which requires the name of the window class
to instantiate and returns a handle to the newly created window.
Expand All @@ -169,14 +169,14 @@
window object take the \texttt{HWND} as a parameter.
\cite{creatingwindow,whatiswindow}

\subsection{Window messages and procedures} % Todo: Citations!
\subsection{Window messages and procedures}
Window classes determine the behavior of window objects. The mechanism
through which window object behavior is defined is the reaction of
a window object to messages sent to the object. The callback that
is called when a window object receives a window message is called
\textit{Window procedure} and is part of the window class, i.e., when
registering a window class, a pointer to the window procedure for the
window class must be provided. The window
registering a window class, application developers must provide a pointer to the window procedure for the
window class. The window
procedure requires four parameters: The \texttt{HWND} of the window
object that received the window message, a numeric code detailing the
type of the message received, and two parameters for the message.
Expand All @@ -186,7 +186,7 @@
Typical types of messages are requests to repaint some
region of the window, notifications about user input, or the notification
that the application is about to exit. If a message is not handled
by the window procedure, it must call \texttt{DefWindowProc},
by the window procedure, the window procedure must call \texttt{DefWindowProc},
resulting in execution of a default window procedure to ensure that
all messages are handled. \cite{aboutwinproc}

Expand All @@ -195,7 +195,7 @@
message loop immediately after creating the main application
window\footnote{In particular, creation of components on the main
window is performed in the message handler for the
\texttt{WM\_CREATE} message, so the main application window will
\texttt{WM\_CREATE} message, so the main application window does
not display any controls or content before the main thread enters
the message loop.}. Applications may fetch the next message in the
queue using \texttt{GetMessage}. The application then has to pass
Expand All @@ -214,7 +214,7 @@
is part of the message record fetched by \texttt{GetMessage}. \cite{messages}


\section{NT Kernel support for GUI applications}\label{sec:win32k}
\section{Win32 drawing APIs}
\begin{figure*}
\centering
\begin{tikzpicture}[yscale=0.7, xscale=1.3]
Expand Down Expand Up @@ -263,86 +263,6 @@
GPU with appropriate drivers.}
\label{fig:arch}
\end{figure*}

The functions available to the user for creating GUI applications are
exported by \texttt{user32.dll}, which is a user-space library.
However, the actual functionality is provided by a kernel module called
\texttt{win32k.sys}. Refer to Figure~\ref{fig:arch} for an overview over the
components involved in the Windows Graphical User Interface. \cite{probertwin32k}

\texttt{win32k} maintains a list of all active GUI threads of the
current session. A GUI thread is somewhat circularly defined as a
thread that is known to \texttt{win32k} as a GUI thread. Upon creation,
a thread is not a GUI thread. A thread is promoted to a GUI thread when
it first calls into \texttt{win32k}, for example when calling
\texttt{CreateWindowEx} from \texttt{user32.dll}. After a thread is
promoted, \texttt{win32k} becomes aware of the thread (and in
particular, is notified of its destruction). In addition, the thread
receives a bigger kernel stack, because \texttt{win32k} call chains
can become rather deep and some specific mechanisms employed by \texttt{win32k}
require extra stack space.
\cite{probertwin32k,mandy2011kernel}

Besides managing GUI threads, \texttt{win32k} contains the kernel portion
of window management. It responds to requests to create and close windows
and keeps a list of all top-level windows of the window station.
\cite{probertwin32k,goingdeep}

Another major responsibility of \texttt{win32k} is the \textit{Raw Input
Thread} (RIT). The RIT is responsible for receiving user input and posting
messages to the correct window\footnote{Implementation details of the
RIT appear to be undocumented. The ReactOS implementation of
the Raw Input Thread continuously and actively polls mouse and keyboard
in turn. If the driver returns a new input, the recipient top-level \texttt{HWND}
is determined. In case of keyboard input or a mouse event while the mouse
has been captured by an application, the active or capturing application
receives the message, respectively. In case of a mouse event while the
mouse is not caputured, all top-level windows are enumerated and the
window the mouse is above is selected.\winver{ROS}}.
\cite{probertwin32k}

\winsubsection{Moving \texttt{win32k} to the kernel}{NT4}
It is possible to provide the functionality described in Section~\ref{sec:win32k}
using a user space module. Even further, proper microkernel design principles
mandate that \texttt{win32k} \emph{must} be placed in user space, because
it is not inherently reliant on kernel mode functionality.
In fact, Windows versions prior to Windows NT 4.0
do implement \texttt{win32k} functionality in user space. However,
in Windows NT 4.0 \texttt{win32k} was moved to kernel space for
performance reasons. Windows NT 3.51 contains a large number of optimizations
to be able to support a user-space \texttt{win32k}, many of them related
to efficient execution of GDI operations (cf. Section~\ref{sec:gdi}).
For example, GDI operations requested by the applications are not
actually drawn immediately by calling into the kernel and communicating
with the graphics hardware. Instead, GDI operations are placed in a
queue. Once the queue is full or is flushed manually by the application,
\texttt{gdi32} switches
into kernel mode and executes all queued operations
in sequence. Symmetrically, \texttt{win32k} data which is available to the application
is cached in user space.
Many (though not all) of these optimizations become unnecessary when
\texttt{win32k} is moved into kernel space, achieving a simpler implementation
with improved performance.
\cite{gdikernel}

The architectural justification for this change is that the subsystem
retains its microkernel-like interface while providing significantly
improved performance. This style of kernel architecture is referred
to as \emph{modified microkernel}. \cite{gdikernel}

Moving \texttt{win32k} from user mode to kernel mode without fundamentally
adapting its architecture---which would be very challenging due to
compatibility---has created an entire class of security problems.
In several situations arising in the context of \texttt{win32k},
calling back from the kernel into user mode code (rather than just
returning) is necessary. In order to facilitate this, \texttt{win32k}
provides a mechanism called \textit{user-mode callbacks}. This
functionality has shown to be very prone to creating security problems,
such as information leakage or transitioning back into user mode after
a different code execution vulnerability has already been exploited.
\cite{mandy2011kernel}

\section{Win32 drawing APIs}
After registering a window, an application has to draw its client area
to the screen. Windows provides multiple APIs to accomplish this task.

Expand Down Expand Up @@ -433,7 +353,7 @@
\cite{goingdeep}

\subsection{Cross-platform graphics APIs}
Besides the essentially Windows-specific DirectX API, there are several
Beside the essentially Windows-specific DirectX API, there are several
cross-platform APIs that aim to fill a similar niche\footnote{Notably,
DirectX does not fill a single niche. In particular,
different versions of the DirectX API emphasize different usage models.
Expand All @@ -449,12 +369,12 @@
OpenGL is officially supported by Windows. Drivers for OpenGL are
loaded through a mechanism called \textit{installable client
drivers} (ICDs). Microsoft provides a module called
\texttt{opengl32.dll} which will then check a specific registry key
\texttt{opengl32.dll} which checks a specific registry key
for a vendor-provided OpenGL driver. If such a driver is found,
OpenGL calls will be relayed to this driver. Otherwise, a
default implementation provided by Microsoft will be used. Regardless
OpenGL calls are relayed to this driver. Otherwise, a
default implementation provided by Microsoft is used. Regardless
of which OpenGL implementation is used, Windows OpenGL applications first obtain
a GDI device context via \texttt{getDC(HWND)} and then pass this device
a GDI device context via the standard GDI function \texttt{getDC(HWND)} and then pass this device
context to the Microsoft-provided function \texttt{wglCreateContext}
to obtain an OpenGL rendering context for use in the cross-platform portion
of the application. \cite{oglrc,oglicd}
Expand All @@ -470,6 +390,85 @@
this surface has been created, the rest of the code of a Vulkan
application is platform-agnostic \cite{vulkanspec}.

\section{NT Kernel support for GUI applications}\label{sec:win32k}
The functions available to the user for creating GUI applications are
exported by \texttt{user32.dll}, which is a user-space library.
However, the actual functionality is provided by a kernel module called
\texttt{win32k.sys}. Refer to Figure~\ref{fig:arch} for an overview over the
components involved in the Windows Graphical User Interface. \cite{probertwin32k}

\texttt{win32k} maintains a list of all active GUI threads of the
current session. A GUI thread is somewhat circularly defined as a
thread that is known to \texttt{win32k} as a GUI thread. Upon creation,
a thread is not a GUI thread. A thread is promoted to a GUI thread when
it first calls into \texttt{win32k}, for example when calling
\texttt{CreateWindowEx} from \texttt{user32.dll}. After a thread is
promoted, \texttt{win32k} becomes aware of the thread (and in
particular, is notified of its destruction). In addition, the thread
receives a bigger kernel stack, because \texttt{win32k} call chains
can become rather deep and some specific mechanisms employed by \texttt{win32k}
require extra stack space.
\cite{probertwin32k,mandy2011kernel}

Besides managing GUI threads, \texttt{win32k} contains the kernel portion
of window management. It responds to requests to create and close windows
and keeps a list of all top-level windows of the window station.
\cite{probertwin32k,goingdeep}

Another major responsibility of \texttt{win32k} is the \textit{Raw Input
Thread} (RIT). The Raw Input Thread is responsible for receiving user input and posting
messages to the correct window\footnote{Implementation details of the
RIT appear to be undocumented. The ReactOS implementation of
the Raw Input Thread continuously and actively polls mouse and keyboard
in turn. If the driver returns a new input, the recipient top-level \texttt{HWND}
is determined. In case of keyboard input or a mouse event while the mouse
has been captured by an application, the active or capturing application
receives the message, respectively. In case of a mouse event while the
mouse is not caputured, all top-level windows are enumerated and the
window the mouse is above is selected.\winver{ROS}}.
\cite{probertwin32k}

\winsubsection{Moving \texttt{win32k} to the kernel}{NT4}
It is possible to provide the functionality described in Section~\ref{sec:win32k}
using a user space module. Even further, proper microkernel design principles
mandate that \texttt{win32k} \emph{must} be placed in user space, because
it is not inherently reliant on kernel mode functionality.
In fact, Windows versions prior to Windows NT 4.0
do implement \texttt{win32k} functionality in user space. However,
in Windows NT 4.0 \texttt{win32k} was moved to kernel space for
performance reasons. Windows NT 3.51 contains a large number of optimizations
to be able to support a user-space \texttt{win32k}, many of them related
to efficient execution of GDI operations (see Section~\ref{sec:gdi}).
For example, GDI operations requested by the applications are not
actually drawn immediately by calling into the kernel and communicating
with the graphics hardware. Instead, GDI operations are placed in a
queue. Once the queue is full or is flushed manually by the application,
\texttt{gdi32} switches
into kernel mode and executes all queued operations
in sequence. Symmetrically, \texttt{win32k} data which is available to the application
is cached in user space.
Many (though not all) of these optimizations become unnecessary when
\texttt{win32k} is moved into kernel space, achieving a simpler implementation
with improved performance.
\cite{gdikernel}

The architectural justification for this change is that the subsystem
retains its microkernel-like interface while providing significantly
improved performance. This style of kernel architecture is referred
to as \emph{modified microkernel}. \cite{gdikernel}

Moving \texttt{win32k} from user mode to kernel mode without fundamentally
adapting its architecture---which would be very challenging due to
compatibility---has created an entire class of security problems.
In several situations arising in the context of \texttt{win32k},
calling back from the kernel into user mode code (rather than just
returning) is necessary. In order to facilitate this, \texttt{win32k}
provides a mechanism called \textit{user-mode callbacks}. This
functionality has shown to be very prone to creating security problems,
such as information leakage or transitioning back into user mode after
a different code execution vulnerability has already been exploited.
\cite{mandy2011kernel}

\section{Window Management}
The window manager is the component of a window-based graphical user
interface that is responsible for managing the position of each active
Expand All @@ -484,18 +483,18 @@
of their windows directly onto the screen buffer. In particular,
this means that all applications draw to the same memory buffer and
when a window is moved on top of another window, that window's data
will be overwritten.
is overwritten.

Non-compositing window managers are efficient and relatively
Non-compositing window managers are efficient and
straightforward to implement. However, there are drawbacks
to this approach. One such drawback is that it inherently comes
to this approach. It inherently comes
with visual artifacts. Because window contents are drawn
directly on the screen without any form of double buffering, screen
tearing will be visible during high-motion events such as scrolling
tearing is visible during high-motion events such as scrolling
text. Additionally, in a situation where a window is moved on top
of an unresponsive window and subsequently moved away, requests to
redraw the region of the bottom window which is now visible again
will be sent, but not handled because the application is not
are sent, but not handled because the application is not
responsive. The result is the well-known \enquote{trail} effect
observed in old versions of Microsoft Windows. Refer to
Figure~\ref{fig:trail} for an example of the problem.
Expand Down Expand Up @@ -564,7 +563,7 @@
engine comes with support for occlusion culling---i.e.,
determining which parts of a window are visible at a particular
moment. This feature completely takes care of the task to
determine which parts of a window should be drawn. Similarly, the
determine which parts of a window should be redrawn. Similarly, the
entire logic that decides when to request which region of which window
to redraw (scheduling and dirty region management) is identical to
its counterpart in Avalon.
Expand Down Expand Up @@ -619,7 +618,7 @@
However, the Desktop Window Manager \emph{is} a DirectX appliction that
by design both runs alongside other DirectX applications and whose
memory consumption is dependent on the number of open windows and therefore
very unpredictable.
unpredictable.
In order to address these problems, display drivers targeting Longhorn
have to be written against the Windows Display Driver Model. This
display driver framework introduces the cooperative multitasking
Expand Down Expand Up @@ -655,21 +654,21 @@
drawing to. \cite{dwmredirect}

The desktop window manager cannot run without a WDDM-compliant
display driver \cite{dwmwddm}. If no such driver is available, one
of two things will happen, depending on the version of Windows that
is running. Under Windows Vista and Windows 7, DWM will be
display driver \cite{dwmwddm}. If no such driver is available,
\texttt{win32k} \cite{probertwin32k} performs one of two actions, depending on the version of Windows that
is running. Under Windows Vista and Windows 7, DWM is
disabled\footnote{In Windows Vista and 7, there are some other ways for
DWM to be disabled. Applications can disable the DWM manually (for
example immediately before switching to full-screen mode)
\cite{disabledwm}, or DWM can be automatically disabled when an
application uses the drawing APIs incorrectly, drawing directly
to the screen \cite{dwmredirect}.}
\cite{disabledwm}. Furthermore, DWM shuts down if an application
bypasses compositing and instead draws directly to the screen
\cite{dwmredirect}.}
and the non-compositing window manager\footnote{Contrary to the DWM,
the non-compositing window manager referred to as \textit{USER} resides
in \texttt{win32k} and thus in kernel space \cite{probertwin32k}.}
from Windows XP will be used. When running Windows 8 or later,
the DWM will be run, but a software-based renderer called
\textit{Microsoft Basic Display Adapter} will serve as a replacement
from Windows XP is used. When running Windows 8 or later,
the DWM runs, but a software-based renderer called
\textit{Microsoft Basic Display Adapter} serves as a replacement
for the display driver \cite{dwmalwayson}.

From a GPU driver developer's point of view, a WDDM driver consists
Expand All @@ -686,7 +685,7 @@
other GUI-related components.
\cite{wddmarch,d2dvsgdi}

\winsubsection{Hardware-accelerated GDI ren\-der\-ing}{7}
\winsubsection{GDI hardware acceleration}{7}
During Longhorn development, having GDI directly render to DirectX
surfaces in video memory was deemed infeasible. The problem
was not that GDI calls
Expand Down

0 comments on commit 44d2674

Please sign in to comment.