By calling the RequestDeviceNotifications function with a device interface GUID of DEVCLASS_STREAM_GUID, an application can receive messages from Device Manager to identify loaded stream drivers programmatically. RequestDeviceNotifications supersedes the EnumDevices function.
Kernel-Mode and User-Mode Drivers
Drivers can either run in the kernel memory space or in user memory space. In kernel mode, drivers have full access to the hardware and kernel memory, although function calls are generally limited to kernel APIs. Windows Embedded CE 6.0 runs drivers in kernel mode, by default. On the other hand, drivers in user mode do not have direct access to kernel memory. There are some performance penalties when running in user mode, yet the advantage is that a driver failure in user mode only affects the current process, whereas the failure of a kernel-mode driver can impair the entire operating system. The system can generally recover more gracefully from the failure of a user-mode driver.
Kernel drivers cannot display a user interface directly in CE 6.0 R2. To use any user interface elements, developers must create a companion DLL that will be loaded into user-mode, then call into this DLL with CeCallUserProc. For more information on CeCallUserProc, see the MSDN Web page at http://msdn2.microsoft.com/en-us/library/aa915093.aspx.
User-Mode Drivers and the Reflector Service
In order to communicate with the underlying hardware and perform useful tasks, user-mode drivers must be able to access system memory and privileged APIs unavailable to standard user-mode processes. To facilitate this, Windows Embedded CE 6.0 features a Reflector service, which runs in kernel mode, performs buffer marshaling, and calls privileged memory management APIs on behalf of the user- mode drivers. The Reflector service is transparent so that user-mode drivers can work almost the same way as kernel-mode drivers without modifications. An exception to this rule is a driver that uses kernel APIs that are not available in user mode. It is not possible to run these types of kernel-mode drivers in user mode.
When an application calls ActivateDeviceEx, Device Manager loads the driver either directly in kernel space or passes the request to the Reflector service, which in turn starts a user mode driver host process (Udevice.exe) through a CreateProcess call. The Flags registry entry in the driver's registry key determines whether a driver should run in user mode (DEVFLAGS_LOAD_AS_USERPROC flag). Having started the required instance of Udevice.exe and user-mode driver, the Reflector service forwards the XXX_Init call from Device Manager to the user-mode driver and returns the return code from the user-mode driver back to Device Manager, as indicated in Figure 6-5. The same proxy principle also applies to all other stream functions.
Figure 6-5 User-mode drivers, kernel-mode drivers, and the Reflector service
User-Mode Drivers Registry Settings
On Windows Embedded CE 6.0, you can run multiple user-mode drivers in a single host process or have multiple host processes enabled on the system. Drivers grouped in a single Udevice.exe instance share the same process space, which is particularly useful for drivers that depend on each other. However, drivers in the same process space can affect each other's stability. For example, if a user-mode driver causes the host process to fail, all drivers in that host process fail. The system continues to function except for the affected drivers and applications accessing these drivers, yet it is possible to recover from this situation by reloading the drivers, if the applications support it. If you isolate a critical driver in a separate user mode driver host process, you can increase the overall system stability. By using the registry entries listed in Table 6-5, you can define individual host process groups.
Table 6-5 Registry entries for user-mode driver host processes
Registry Entry | Type | Description |
---|---|---|
HKEY_LOCAL_MACHINE\Drivers\ProcGroup_### | REG_KEY | Defines a three-digit group ID (###) for a user-mode driver host process, such as ProcGroup_003, which you can then specify in the UserProcGroup entry in a driver's registry key, such as UserProcGroup=3. |
ProcName | REG_SZ | The process that the Reflector service starts to host the user-mode driver, such as ProcName=Udevice.exe. |
ProcVolPrefix | REG_SZ | Specifies the file system volume that the Reflector service mounts for the user-mode driver host process, such as ProcVolPrefix=$udevice. The specified ProcVolPrefix replaces the $device volume in driver device names. |