User mode and kernel mode
A processor in a computer running Windows has two different modes: user mode and kernel mode. The processor switches between the two modes depending on what type of code is running on the processor. Applications run in user mode, and core operating system components run in kernel mode. While many drivers run in kernel mode, some drivers may run in user mode.
When you start a user-mode application, Windows creates a process for the application. The process provides the application with a private virtual address space and a private handle table. Because an application’s virtual address space is private, one application cannot alter data that belongs to another application. Each application runs in isolation, and if an application crashes, the crash is limited to that one application. Other applications and the operating system are not affected by the crash.
In addition to being private, the virtual address space of a user-mode application is limited. A processor running in user mode cannot access virtual addresses that are reserved for the operating system. Limiting the virtual address space of a user-mode application prevents the application from altering, and possibly damaging, critical operating system data.
All code that runs in kernel mode shares a single virtual address space. This means that a kernel-mode driver is not isolated from other drivers and the operating system itself. If a kernel-mode driver accidentally writes to the wrong virtual address, data that belongs to the operating system or another driver could be compromised. If a kernel-mode driver crashes, the entire operating system crashes.
This diagram illustrates communication between user-mode and kernel-mode components.
Connecting and Configuring Displays
This section applies only to WindowsВ 7 and later, and Windows ServerВ 2008В R2 and later versions of the MicrosoftВ Windows operating system.
The new Connecting and Configuring Displays (CCD) Win32 APIs that are described in CCD DDIs provide more control over the desktop display setup. They can also be used to make your app display correctly on a portrait device. For example, in versions of Windows prior to WindowsВ 7, it was impossible to set clone mode by using the ChangeDisplaySettingsEx function. The new CCD APIs move away from using Windows Graphics Device Interface (GDI) concepts like view name and toward Windows Display Driver Model (WDDM) concepts like adapter, source, and target identifiers.
The display control panel, new hot keys, and the Hot Plug Detection (HPD) manager can use the CCD APIs. OEMs can use the CCD APIs for their value-add applets instead of using private driver escapes.
The CCD APIs provide the following functionality:
Enumerate the display paths that are possible from the currently connected displays.
Set the topology (for example, clone and extend), layout information, resolution, orientation, and aspect ratio for all the connected displays in one function call. By performing multiple settings for all connected displays in one function call, the number of screen flashes is reduced.
Add or update settings to the persistence database.
Apply settings that are persisted in the database.
Use best mode logic to apply optimum display settings.
Use best topology logic to apply the optimum topology for the connected displays.
Start or stop forced output.
Allow OEM hot keys to use the new operating system persistence database.
The CCD APIs cannot handle the following tasks. In addition, the CCD APIs are not backward compatible with the Windows 2000 display driver model.
Replace the API sets and private driver escapes that hardware vendors previously provided to control desktop display setup.
Pass private data down to the kernel-mode display miniport driver.
Provide a new set of monitor-control APIs.
Query the monitor capabilities, which include EDID, DDCCI, and so on.
Provide a context identifier to uniquely identify the settings that the CCD APIs retrieve from the persistence database.
Although the CCD APIs allows a caller to get and set the displays, they do not provide any functionality to enumerate the possible source modes in a given path. APIs that existed prior to WindowsВ 7 already provide this functionality.
The following sections describe the CCD APIs in more detail:
NoteВ В In addition to using the CCD APIs to set up the desktop display, hardware vendors must modify their WindowsВ 7В Windows Display Driver Model (WDDM) display miniport drivers to support CCD. For more information about supporting CCD in display miniport drivers, see CCD DDIs.
Initializing Communication with the Direct3D User-Mode Display Driver
To initialize communication with the Microsoft Direct3D user-mode display driver DLL’s version 11 DDI, the Direct3D runtime first loads the DLL. The Direct3D runtime next calls the user-mode display driver’s OpenAdapter function through the DLL’s export table to open an instance of the graphics adapter. The OpenAdapter function is the DLL’s only exported function.
In the call to the driver’s OpenAdapter function, the runtime supplies the pfnQueryAdapterInfoCb adapter callback function in the pAdapterCallbacks member of the D3DDDIARG_OPENADAPTER structure. The runtime also supplies its version in the Interface and Version members of D3DDDIARG_OPENADAPTER. The user-mode display driver must verify that it can use this version of the runtime. The user-mode display driver returns a table of its adapter-specific functions in the pAdapterFuncs member of D3DDDIARG_OPENADAPTER.
The user-mode display driver should call the pfnQueryAdapterInfoCb adapter callback function to query for the graphics hardware capabilities from the display miniport driver.
The runtime calls the user-mode display driver’s CreateDevice function (one of the driver’s adapter-specific functions) to create a display device for handling a collection of render state and to complete the initialization. When the initialization is complete, the Direct3D runtime can call the display driver-supplied functions, and the user-mode display driver can call the runtime-supplied functions.
The user-mode display driver’s CreateDevice function is called with a D3DDDIARG_CREATEDEVICE structure whose members are set up in the following manner to initialize the user-mode display driver interface:
The runtime sets Interface to the version of the interface that the runtime requires from the user-mode display driver.
The runtime sets Version to a number that the driver can use to identify when the runtime was built. For example, the driver can use the version number to differentiate between a runtime released with Windows Vista and a runtime released with a subsequent service pack, which might contain a fix that the driver requires.
The runtime sets hDevice to specify the handle that the driver should use when the driver calls back into the runtime. The driver generates a unique handle and passes it back to the runtime in hDevice. The runtime should use the returned hDevice handle in subsequent driver calls.
The runtime supplies a table of its device-specific callback functions in the D3DDDI_DEVICECALLBACKS structure to which pCallbacks points. The user-mode display driver calls the runtime-supplied callback functions to access kernel-mode services in the display miniport driver.
The user-mode display driver returns a table of its device-specific functions in the D3DDDI_DEVICEFUNCS structure to which pDeviceFuncs points.
The number of display devices (graphics contexts) that can simultaneously exist is limited only by available system memory.
Пользовательский режим (user mode) и режим ядра (kernel mode)
Понятие «пользовательский режим» и «режим ядра» относятся к операционной системе. С этими понятиями тесно связано понятие уровней привилегий процессоров, но это не одно и то же. ОС Windows в процессорах архитектуры x86 использует два уровня 0 и 3:
Операционная система Windows отвечает за переключение между пользовательским режимом и режимом ядра. Таким образом, когда выполняется код ОС или драйвера, он выполняется на 0 уровне процессора x86, который не имеет каких-либо ограничений. Если же выполняется код в пользовательском режиме — то это происходит на 3 уровне.
В принципе нам достаточно знать, что разработчики процессоров предусмотрели специальный механизм уровней привилегий, пойдя навстречу разработчикам операционных систем. Это сделано для того, чтобы сделать систему в целом более стабильной и менее подверженной сбоям из-за некачественно написанного программного обеспечения.
Для этого механизма также распространено название – rings (кольца защиты).
Хотя на рисунке видно, что драйвера Windows используют 1,2 уровень для Windows это не так, как уже было сказано (рисунок описывает возможность процессоров архитектуры x86). Возможно, в какой-либо другой операционной системе используются и эти уровни.
Итак, если программа, которая выполняется в пользовательском режиме, обратится по адресу памяти, который не существует, то мы получим только крах этой программы, закроем ее и запустим заново. Если же это произойдет в режиме ядра, то мы получим синий экран смерти (BSOD).
Большинство синих экранов смерти, порядка 70% (согласно статистики Microsoft) происходит из-за ошибок в драйверах сторонних разработчиков.
Выгода от такого подхода с привилегиями в том, что обычным программам, таким как браузеры, игры, текстовые редакторы и т.д., работать в режиме ядра не нужно, соответственно в случае их краха стабильность системы в целом не пострадает. Код, который написан для режима ядра, обычно более тщательно оттестирован, а его количество значительно меньше. Кроме того, чтобы установить драйвер, который работает в режиме ядра, нужны права Администратора. Таким образом, можно ограничить количество людей, имеющих возможность установить код, который может повлиять на работу системы в целом, что обычно и делается во многих организациях.
Однако в Windows драйвера могут частично работать и в пользовательском режиме, примером тому могут быть WDDM драйвера видео в Windows Vista.
Если вы работаете с правами обыкновенного пользователя, что я настоятельно рекомендую всегда делать, вы достигаете большего уровня защищенности и стабильности системы. Даже если вы запустите исполняемый файл с вирусом, вирус не сможет внедрится в систему на уровне ядра и например попытаться скрыть свое присутствие от антивируса или перехватывать данные вводимые вами с клавиатуры через свой драйвер.
Вы можете легко увидеть в своей системе, сколько процессорного времени отдается на исполнение кода в режиме ядра, а сколько пользовательскому режиму. Для этого выберите Пуск / Выполнить, введите perfmon и нажмите enter для того, чтобы запустить оснастку Системный монитор («Производительность» для Windows XP).
В панели инструментов выбираем «Добавить», далее выбираем счетчик процессор и, удерживая Ctrl, выбираем:
Нажимаем «Добавить» и «ОК».
Также наблюдать за загрузкой ЦП в режиме ядра можно с помощью диспетчера задач. Для этого вначале запускаем его (самый просто способ – Ctrl + Shift + Esc), далее выбираем “Вид / вывод времени ядра”.
Красная часть на графике относится к загрузке во время выполнения кода ядра. Как видим, часть процессорного времени тратится на исполнение кода в режиме ядра, а часть в пользовательском режиме.
Если мы работаем в системе с правами обыкновенного пользователя, а не администратора то вероятность получить вирус, из-за которого могут возникать синие экраны смерти, равна нулю.
Причиной BSOD может быть только код, который работает в режиме ядра. Поэтому если у вас было все хорошо, а после установки антивируса, начали возникать синие экраны смерти, причина, скорее всего в нем. Достаточно удалить антивирус и проследить за тем, происходит ли крах системы или нет.
Miracast user-mode driver tasks to support Miracast wireless displays
As of Windows 10, the OS contains a native implementation of Miracast wireless displays. Drivers should no longer implement a custom Miracast display component. Support for custom Miracast implementations may be removed in a future version of Windows.
To enable Miracast wireless displays, you need to create a standalone, unique DLL that implements a Miracast user-mode driver. This driver will be loaded in a dedicated session 0 process. Add the name of the driver in device software settings in the INF file as MiracastDriverName:
The DLL should have an export function named QueryMiracastDriverInterface that the operating system can call. This driver binary must not use an existing Microsoft Direct3D user-mode display driver DLL.
Note that because the Miracast user-mode driver is loaded into the UMDF0 process, no separate Windows on Windows (WOW) version of this driver is needed. For example, on a 64-bit processor a 64-bit version of the driver is used.
When the operating system is ready to prepare for a Miracast connected session, it calls the Miracast user-mode driver’s CreateMiracastContext function. When this function is called, the Miracast user-mode driver allocates all the software resources it needs to start a Miracast connected session. In this call the operating system also provides pointers to callback functions that the driver can call during the lifetime of the current Miracast context. Then after a Real-Time Streaming Protocol (RTSP) link is established, the operating system calls StartMiracastSession to actually start the Miracast connected session. When responding to this function call, the driver should use the Winsock getaddrinfo function, or other relevant functions, to get the Internet Protocol (IP) address of the Miracast sink and use standard Winsock functions to create a Hypertext Caching Protocol (HTCP) Remote Desktop Protocol (RDP) socket.
If a Miracast display becomes available, the Miracast user-mode driver calls the operating system-supplied MiracastIoControl function to send an I/O control request to the display miniport driver to report a monitor arrival hot-plug detection (HPD) awareness value. The Miracast user-mode driver should also query Miracast sink info and capabilities and report some of this info, such as the monitor description, to the display miniport driver by calling MiracastIoControl.
After the Miracast connected session has been started, and after streaming data has been prepared and before sending it to the network, the driver needs to call the ReportStatistic callback function to report the statistics of the Miracast link to the operating system.
When the operating system stops a Miracast connected session, it calls the Miracast user-mode driver’s StopMiracastSession function. In response to this function call, the driver should close all the sockets it created and drop all the further data streaming. The driver should not close the RTSP socket that the operating system gave it. It also should not send a request to the display miniport driver to report an HPD on monitor departure.
In responding to the operating system’s calls to the DestroyMiracastContext function, the Miracast user-mode driver should release all the software resources that it allocated in CreateMiracastContext.
When the display miniport driver receives a DxgkDdiCommitVidPn request to power off the connected Miracast monitor, the driver should call the operating system-supplied DxgkCbMiracastSendMessage callback function to send a message to the Miracast user-mode driver. The Miracast user-mode driver should then put the Miracast sink into a low-power state.
The RegisterForDataRateNotifications callback function can optionally be called by the Miracast user-mode driver to register with the operating system to receive, once a second, network quality of service (QoS) notifications and the current network bandwidth of the Miracast connection. This network info is provided by operating system calls to the pfnDataRateNotify function.
The Miracast user-mode driver can also call these optional callback functions provided by the operating system:
GetNextChunkData
Provides info about the next encode chunk.
ReportSessionStatus
The driver calls this function to report the status of the current Miracast connected session.