Managing Pointers in Device Drivers

Other versions of this page are also available for the following:

Windows Mobile Not SupportedWindows Embedded CE Supported

8/28/2008

The operating system (OS ) manages pointers passed directly as parameters. Drivers must map all pointers contained in structures. DeviceIoControl buffers are often structures that contain data, some of which might be pointers.

You can map a pointer contained in a structure by calling MapPtrToProcess, setting the first parameter to the pointer, and then setting the second parameter to GetCallerProcess.

You cannot prevent one thread in an application that has called HeapAlloc from having its memory freed by a rogue thread in the same application. Although you can hide the memory pointer by making it a local variable, threads can access any memory in their process context.

Drivers are privileged parts of the OS. You can use MapCallerPtr to allow drivers to verify that buffer pointers, up to a specified size, are valid in the context of the calling process. Doing so prevents you from interfering with memory space that belongs to other processes. Device Manager calls MapCallerPtr for parameters to all driver entry points, if the calling process is set to the normal level of priviledge. Because privileged code should not pass malicious pointers, you must make a system call to validate the pointer, which slightly impacts performance. If an IOCTL buffer contains nested pointers, the driver must call MapCallerPtr to map these pointer values for Device Manager.

You cannot page data sections to a page file. You can discard and reload read-only code pages on demand, unless they cannot be paged. Driver code pages cannot be paged. Because memory-mapped files are supported, a write to a memory-mapped data page passes through to the underlying storage. Application data is never moved or paged out. Generally, it is not necessary to lock pages unless your driver is in the critical paging path, or you are performing direct memory access (DMA) directly to or from the user's buffer.

A device driver gains access to the data in the address space of an application by calling MapPtrToProcess. The following list shows how a driver gains access to memory in the address space of an application. This process is required only when you pass a pointer to a pointer, as might occur with a linked list, not when you pass a simple pointer to a device driver.

  1. The OS maps the application to slot 0 (zero).
  2. The application calls DeviceIoControl.
  3. The OS maps Device Manager to slot 0 (zero).
  4. Device Manager sets permissions to application space.
    Permission is not necessary if the application space is within the same PSL call because the driver automatically gets the permission to the caller process.
  5. Device Manager calls XXX_IOControl (Device Manager).
  6. The driver calls MapPtrToProcess.
  7. The driver returns from XXX_IOControl.
  8. Device Manager resets permissions to application space.
    Permission is not necessary if the application space is within the same PSL call because the permission is automatically reset upon returning to the caller process.
  9. The OS maps the application to slot 0 (zero).

See Also

Concepts

Accessing Memory from a Driver

Other Resources

GetCurrentProcessId
GetOwnerProcess
Memory Architecture