Wednesday, February 11, 2015

[0x0009] Write a KMDF driver based on a template

Write a KMDF driver based on a template

To write a Kernel-Mode Driver Framework (KMDF) driver, you can use a Microsoft Visual Studio template. To get started, be sure you have Visual Studio and the Windows Driver Kit (WDK) installed. You can download them from the Windows Hardware Dev Center.
Debugging Tools for Windows is included when you install the WDK.

Create and build a driver package

  1. Open Microsoft Visual Studio. On the File menu, choose New > Project. The New Project dialog box opens, as shown here.
  2. In the New Project dialog box, select WDF.
  3. In the middle pane, select Kernel Mode Driver (KMDF).
  4. In the Name field, enter "KmdfDriver" as the project name.
    Note  When you create a new KMDF or UMDF driver, you must select a driver name that has 32 characters or less. This length limit is defined in wdfglobals.h.
  5. In the Location field, enter the directory where you want to create the new project.
  6. Check Create directory for solution. Click OK.
    Screen shot of the New Project dialog box, showing WDF and Kernel Mode Driver selected
    Visual Studio creates two projects and a solution. You can them in the Solution Explorer window, as shown here. (If the Solution Explorer window is not visible, choose Solution Explorer from the View menu.) The solution has a driver project named KmdfDriver and a driver package project named KmdfDriver Package. To see the driver source code, open any of the files under Source Files. Driver.c and Device.c are good places to start.
    Screen shot of Solution Explorer showing the files in the driver project and the package project
  7. In the Solution Explorer window, right-click Solution 'KmdfDriver' (2 projects), and chooseConfiguration Manager. Choose a configuration and platform for both the driver project and the package project. In this exercise, we choose Win 8.1 Debug and x64.
  8. To build your driver and create a driver package, choose Build Solution from the Build menu. Visual Studio shows the build progress in the Output window. (If the Output window is not visible, choose Outputfrom the View menu.)
    When you've verified that the solution built successfully, you can close Visual Studio.
  9. To see the built driver package, in File Explorer, go to your KmdfDriver folder, and then tox64\Win8.1Debug\KmdfDriver Package. The driver package has several files:
    • KmdfDriver.sys -- the kernel-mode driver file
    • KmdfDriver.inf -- an information file that Windows uses when you install the driver
    • KmdfDriver.cat -- a catalog file that the installer uses to verify the test signature for the driver package
    There might also be a coinstaller file in the package.

Deploy and install the driver

Typically when you test and debug a driver, the debugger and driver run on separate computers. The computer that runs the debugger is called the host computer, and the computer that runs the driver is called the target computer. The target computer is also called the test computer. For more information about debugging drivers, see Debugging Tools for Windows.
So far you've used Visual Studio to build a driver on the host computer. Now you need to configure a target computer. ToFollow the instructions in Provision a computer for driver deployment and testing (WDK 8.1). Then you can deploy, install, load, and debug your driver:
  1. On the host computer, open your solution in Visual Studio. You can double-click the solution file, KmdfDriver.sln, in your KmdfDriver folder.
  2. In the Solution Explorer window, right-click KmdfDriver Package, and choose Properties.
  3. In the KmdfDriver Package Property Pages window, in the left pane, go to Configuration Properties > Driver Install > Deployment.
  4. Check Enable deployment, and check Remove previous driver versions before deployment.
  5. For Remote Computer Name, select the name of the computer that you configured for testing and debugging. In this exercise, we use a computer named MyTestComputer.
  6. Select Hardware ID Driver Update, and enter the hardware ID for your driver. In this exercise, the hardware ID is Root\KmdfDriver. Click OK.
    Screen shot of the KmdfDriver Package Property Pages window, showing Deployment Driver Install selected
    Note  In this exercise, the hardware ID does not identify a real piece of hardware. It identifies an imaginary device that will be given a place in the device tree as a child of the root node. For real hardware, do not select Hardware ID Driver Update; instead, select Install and Verify.
    You'll see the hardware ID in your driver's information (INF) file. In the Solution Explorer window, go toKmdfDriver > Driver Files and double-click KmdfDriver.inf. The hardware ID is located under [Standard.NT$ARCH$].
    [Standard.NT$ARCH$]
    %KmdfDriver.DeviceDesc%=KmdfDriver_Device, Root\KmdfDriver
    
    
  7. On the Debug menu, choose Start Debugging, or press F5 on the keyboard.
  8. Visual Studio first shows progress in the Output window. Then it opens the Debugger Immediate Window and continues to show progress.
    Wait until your driver has been deployed, installed, and loaded on the target computer. This might take a minute or two.
  9. On the Debug menu, choose Break All. The debugger on the host computer will break into the target computer. In the Debugger Immediate Window, you'll see the kernel debugging command prompt: kd>.
    Screen shot of the command prompt in the Debugger Immediate window
  10. At this point, you can experiment with the debugger by entering commands at the kd> prompt. For example, you could try these commands:
  11. To let the target computer run again, choose Continue from the Debug menu.
  12. To stop the debugging session, choose Stop Debugging from the Debug menu.

Related topics

Developing, Testing, and Deploying Drivers
Debugging Tools for Windows
Write your first driver


[0x0008] Write a KMDF Hello World driver

Write a KMDF Hello World driver

To write a Kernel-Mode Driver Framework (KMDF) driver, you can use Microsoft Visual Studio along with the Windows Driver Kit (WDK). You can download them from the Windows Hardware Dev Center.
Debugging Tools for Windows is included when you install the WDK.

Create and build a driver package

  1. Open Microsoft Visual Studio. On the File menu, choose New > Project.
  2. In the New Project dialog box, select WDF.
  3. In the middle pane, select Kernel Mode Driver, Empty (KMDF).
  4. In the Name field, enter "KmdfHelloWorld" for the project name.
    Note  When you create a new KMDF or UMDF driver, you must select a driver name that has 32 characters or less. This length limit is defined in wdfglobals.h.
  5. In the Location field, enter the directory where you want to create the new project.
  6. Check Create directory for solution. Click OK.
    Screen shot of the New Project dialog box
    Visual Studio creates two projects and a solution. You can see them in the Solution Explorer window, shown here. (If the Solution Explorer window is not visible, choose Solution Explorer from the View menu.) The solution has a driver project named KmdfHelloWorld and a driver package project named KmdfHelloWorld Package.
    Screen shot of the Solution Explorer window, showing the package project (KmdfHelloWorld Packages) and the empty driver project (KmdfHelloWorld)
  7. In the Solution Explorer window, right-click KmdfHelloWorld and choose Add > New Item.
  8. In the Add New Item dialog box, select C++ File. For Name, enter "Driver.c".
    Note  The file name extension is .c, not .cpp.
    Click Add. The Driver.c file is added under Source Files, as shown here.
    Screen shot of the Solution Explorer window, showing the Driver.c file added to the driver project
  9. Open Driver.c, and enter this code:
    #include <ntddk.h>
    #include <wdf.h>
    DRIVER_INITIALIZE DriverEntry;
    EVT_WDF_DRIVER_DEVICE_ADD KmdfHelloWorldEvtDeviceAdd;
    
    NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT  DriverObject, _In_ PUNICODE_STRING RegistryPath)
    {
        NTSTATUS status;
        WDF_DRIVER_CONFIG config;
     
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "KmdfHelloWorld: DriverEntry\n" ));
        WDF_DRIVER_CONFIG_INIT(&config, KmdfSmallEvtDeviceAdd);
        status = WdfDriverCreate(DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, WDF_NO_HANDLE);
        return status;
    }
    
    NTSTATUS KmdfHelloWorldEvtDeviceAdd(_In_ WDFDRIVER Driver, _Inout_ PWDFDEVICE_INIT DeviceInit)
    {
        NTSTATUS status;
        WDFDEVICE hDevice;
        UNREFERENCED_PARAMETER(Driver);
    
        KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "KmdfHelloWorld: KmdfHelloWorldEvtDeviceAdd\n" ));
        status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &hDevice);
        return status;
    }
    
    
  10. Save Driver.c.
  11. In the Solution Explorer window, right-click Solution 'KmdfHelloWorld' (2 projects) and chooseConfiguration Manager. Choose a configuration and platform for both the driver project and the package project. For this exercise, we choose Win 8.1 Debug and x64.
  12. In the Solution Explorer window, right-click KmdfHelloWorld and choose Properties. In Wpp Tracing > All Options, set Run Wpp tracing to No. Click OK.
  13. To build your driver and create a driver package, choose Build Solution from the Build menu. Visual Studio shows the build progress in the Output window. (If the Output window is not visible, choose Outputfrom the View menu.)
    When you have verified that the solution built successfully, you can close Visual Studio.
  14. To see the built driver package, in File Explorer, go to your KmdfHelloWorld folder, and then toC:\KmdfHelloWorld\x64\Win8.1Debug\KmdfHelloWorld Package. The driver package has several files: and .
    • KmdfHelloWorld.sys -- the kernel-mode driver file
    • KmdfHelloWorld.inf -- an information file that Windows uses when you install the driver
    • KmdfHelloWorld.cat -- a catalog file that the installer uses to verify the test signature for the driver package
    The package might also contain a coinstaller file.

Deploy and install the driver

Typically when you test and debug a driver, the debugger and the driver run on separate computers. The computer that runs the debugger is called the host computer, and the computer that runs the driver is called the target computer. The target computer is also called the test computer.
So far you've used Visual Studio to build a driver on the host computer. Now you need to configure a target computer. Follow the instructions in Provision a computer for driver deployment and testing (WDK 8.1). Then you can deploy, install, load, and debug your driver:
  1. On the host computer, open your solution in Visual Studio. You can double-click the solution file, KmdfHelloWorld.sln, in your KmdfHelloWorld folder.
  2. In the Solution Explorer window, right-click KmdfHelloWorld Package, and choose Properties.
  3. In the KmdfHelloWorld Package Property Pages window, go to Configuration Properties > Driver Install > Deployment, as shown here.
  4. Check Enable deployment, and check Remove previous driver versions before deployment.
  5. For Remote Computer Name, select the name of the computer that you configured for testing and debugging. In this exercise, we use a computer named MyTestComputer.
  6. Select Hardware ID Driver Update, and enter the hardware ID for your driver. For this exercise, the hardware ID is Root\KmdfHelloWorld. Click OK.
    Screen shot showing the KmdfHelloWorld Package Property Pages window with the Deployment Driver Install selected
    Note  In this exercise, the hardware ID does not identify a real piece of hardware. It identifies an imaginary device that will be given a place in the device tree as a child of the root node. For real hardware, do not select Hardware ID Driver Update; instead, select Install and Verify.
    You'll see the hardware ID in your driver's information (INF) file. In the Solution Explorer window, go toKmdfHelloWorld > Driver Files, and double-click KmdfHelloWorld.inf. The hardware ID is located under [Standard.NT$ARCH$].
    [Standard.NT$ARCH$]
    %KmdfHelloWorld.DeviceDesc%=KmdfHelloWorld_Device, Root\KmdfHelloWorld
    
    
  7. On the Debug menu, choose Start Debugging, or press F5 on the keyboard.
  8. Visual Studio first shows progress in the Output window. Then it opens the Debugger Immediatewindow and continues to show progress.
    Wait until your driver has been deployed, installed, and loaded on the target computer. This might take a minute or two.
  9. On the Debug menu, choose Break All. The debugger on the host computer will break into the target computer. In the Debugger Immediate window, you can see the kernel debugging command prompt: kd>.
    Screen shot of the command prompt in the Debugger Immediate window
  10. At this point, you can experiment with the debugger by entering commands at the kd> prompt. For example, you could try these commands:
  11. To let the target computer run again, choose Continue from the Debug menu.
  12. To stop the debugging session, choose Stop Debugging from the Debug menu.

Related topics

Developing, Testing, and Deploying Drivers
Debugging Tools for Windows
Write your first driver


[0x0007] Write a UMDF driver based on a template

Write a UMDF driver based on a template

To write a User-Mode Driver Framework (UMDF) driver, you can use a Microsoft Visual Studio template. To get started, be sure you have Visual Studio and the Windows Driver Kit (WDK) installed. You can download them from the Windows Hardware Dev Center.
Debugging Tools for Windows is included when you install the WDK.

Create and build a driver package

  1. Open Visual Studio. On the File menu, choose New > Project.
  2. In the New Project dialog box, in the left pane, go to Online > Templates.
  3. In the New Project dialog box, in the upper-right corner, search for the template by name: User Mode Driver, WRL (UMDF).
  4. In the Name field, enter "UmdfDriver" as the project name.
    Note  When you create a new KMDF or UMDF driver, you must select a driver name that has 32 characters or less. This length limit is defined in wdfglobals.h.
  5. In the Location field, enter the directory where you want to create the new project.
  6. Check Create directory for solution. Click OK.
    Screen shot of the New Project dialog box, showing WDF and User Mode Driver selected
    Visual Studio creates two projects and a solution. You can see them in the Solution Explorer window. (If theSolution Explorer window is not visible, choose Solution Explorer from the View menu.) The solution has a driver project named UmdfDriver and a driver package project named UmdfDriver Package. To see the driver source code, open any of the files under Source Files. Driver.cpp and Device.cpp are good places to start.
    Screen shot of Solution Explorer showing the files in the driver project and the package project
  7. In the Solution Explorer window, right-click Solution 'UmdfDriver' (2 projects), and chooseConfiguration Manager. Choose a configuration and platform for both the driver project and the package project. For example, choose Win 8.1 Debug and x64.
  8. To build your driver and create a driver package, choose Build Solution from the Build menu. Microsoft Visual Studio displays build progress in the Output window. (If the Output window is not visible, chooseOutput from the View menu.)
    When you've verified that the solution built successfully, you can close Visual Studio.
  9. To see the built driver package, in File Explorer, go to your UmdfDriver folder, and then tox64\Win8.1Debug\UmdfDriver PackageThe driver package has several files:
    • UmdfDriver.dll -- the user-mode driver file
    • UmdfDriver.inf -- an information file that Windows uses when you install the driver
    • UmdfDriver.cat -- a catalog file that contains a test signature for the package
    There might also be a coinstaller file in the package.

Deploy and installing the driver

Typically when you test and debug a driver, the debugger and driver run on separate computers. The computer that runs the debugger is called the host computer, and the computer that runs the driver is called the target computer. The target computer is also called the test computer.
So far, you've used Visual Studio to build a driver on the host computer. Now you need to configure a target computer. Follow the instructions in Provision a computer for driver deployment and testing (WDK 8.1). Then you'll be ready to deploy, install, load, and debug your driver:
  1. On the host computer, open your solution in Visual Studio. You can double-click the solution file, UmdfDriver.sln, in your UmdfDriver folder.
  2. In the Solution Explorer window, right-click UmdfDriver Package, and choose Properties.
  3. In the UmdfDriver Package Property Pages window, go to Configuration Properties > Driver Install > Deployment, as shown here.
  4. Check Enable deployment, and check Remove previous driver versions before deployment.
  5. For Remote Computer Name, select the name of the computer that you configured for testing and debugging. In this exercise, we use a computer named MyTestComputer.
  6. Select Hardware ID Driver Update, and enter the hardware ID for your driver. In this exercise, the hardware ID is Root\UmdfDriver. Click OK.
    Screen shot of the UmdfDriver Package Property Pages, showing Deployment Driver Install selected
    Note  In this exercise, the hardware ID does not identify a real piece of hardware. It identifies an imaginary device that will be given a place in the device tree as a child of the root node. For real hardware, do not select Hardware ID Driver Update; instead, select Install and Verify.
    You can see the hardware ID in your driver's information (INF) file. In the Solution Explorer window, go toUmdfDriver > Driver Files, and double-click UmdfDriver.inf. The hardware ID is under [Standard.NT$ARCH$].
    [Standard.NT$ARCH$]
    %DeviceName%=MyDevice_Install,Root\UmdfDriver
    
    
  7. On the Debug menu, choose Start Debugging, or press F5 on the keyboard.
  8. Wait until your driver has been deployed, installed, and loaded on the target computer. This might take several minutes.

Related topics

Developing, Testing, and Deploying Drivers
Debugging Tools for Windows
Write your first driver


[0x0006] User mode and kernel mode

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. Many drivers run in kernel mode, but some drivers 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.
Block diagram of user-mode and kernel-mode components

Related topics

Virtual Address Spaces


Tuesday, February 10, 2015

[0x0005] Write your first driver

Write your first driver

If you're writing your first driver, use these exercises to get started. Each exercise is independent of the others, so you can do them in any order.
User-Mode Driver Framework (UMDF) and Kernel-Mode Driver Framework (KMDF) are part of the Windows Driver Frameworks (WDF).


[0x0004] Choosing a driver model

Choosing a driver model

Microsoft Windows provides a variety of driver models that you can use to write drivers. The strategy for choosing the best driver model depends on the type of driver you are planning to write. Here are the options:
  • Device function driver
  • Device filter driver
  • Software driver
  • File system filter driver
  • File system driver
For a discussion about the differences between the various types of drivers, see What is a driver? and Device nodes and device stacks. The following sections explain how to choose a model for each type of driver.

Choosing a driver model for a device function driver

As you design a hardware device, one of the first things to consider is whether you need to write a function driver. Ask the following questions:
Can you avoid writing a driver entirely?
If you must write a function driver, what is the best driver model to use?
To answer these questions, determine where your device fits in the list of technologies described in Device and driver technologies. See the documentation for that particular technology to determine whether you need to write a function driver and to learn about which driver models are available for your device.
Some of the individual technologies have minidriver models. In a minidriver model, the device driver consists of two parts: one that handles general tasks, and one that handles device-specific tasks. Typically, Microsoft writes the general portion and the device manufacturer writes the device-specific portion. The device specific portions have a variety of names, most of which share the prefix mini. Here are some of the names used in minidriver models:
  • Display miniport driver
  • Audio miniport driver
  • Battery miniclass driver
  • Bluetooth protocol driver
  • HID minidriver
  • WIA minidriver
  • NDIS miniport driver
  • Storage miniport driver
  • Streaming minidriver
For an overview of minidriver models, see Minidrivers and driver pairs.
Not every technology listed in Device and driver technologies has a dedicated minidriver model. The documentation for a particular technology might advise you to use the Kernel-Mode Driver Framework (KMDF); the documentation for another technology might advise you to use the User-Mode Driver Framework (UMDF). The key point is that you should start by studying the documentation for your specific device technology. If your device technology has a minidriver model, you must use the minidriver model. Otherwise follow the advice in the your technology-specific documentation about whether to use the UMDF, KMDF, or the Windows Driver Model (WDM).

Choosing a driver model for a device filter driver

Frequently several drivers participate in a single I/O request (like reading data from a device). The drivers are layered in a stack, and the conventional way to visualize the stack is with the first driver at the top and the last driver at the bottom. The stack has one function driver and can also have filter drivers. For a discussion about function drivers and filter drivers, see What is a driver? and Device nodes and device stacks.
If you are preparing to write a filter driver for a device, determine where your device fits in the list of technologies described in Device and driver technologies. Check to see whether the documentation for your particular device technology has any guidance on choosing a filter driver model. If the documentation for your device technology does not offer this guidance, then first consider using UMDF as your driver model. If your filter driver needs access to data structures that are not available through UMDF, consider using KMDF as your driver model. In the extremely rare case that your driver needs access to data structures not available through KMDF, use WDM as your driver model.

Choosing a driver model for a software driver

A driver that is not associated with a device is called a software driver. For a discussion about software drivers, see the What is a driver? topic. Software drivers are useful because they can run in kernel mode, which gives them access to protected operating system data. For information about processor modes, seeUser mode and kernel mode.
For a software driver, your two options are KMDF and the legacy Windows NT driver model. With both KMDF and the legacy Windows NT model, you can write your driver without being concerned about Plug and Play (PnP) and power management. You can concentrate instead on your driver's primary tasks. With KMDF, you do not have to be concerned with PnP and power because the framework handles PnP and power for you. With the legacy Windows NT model, you do not have to be concerned about PnP and power because legacy drivers operate in an environment that is completely independent from PnP and power management.
Our recommendation is that you use KMDF, especially if you are already familiar with it. If you want your driver to be completely independent from PnP and power management, use the legacy Windows NT model. If you need to write a software driver that is aware of power transitions or PnP events, you cannot use the legacy Windows NT model; you must use KMDF.
Note  In the very rare case that you need to write a software driver that is aware of PnP or power events, and your driver needs access to data that is not available through KMDF, you must use WDM.

Choosing a driver model for a file system filter driver

For help with choosing a model for a file system filter driver, see File system minifilter drivers and File system filter drivers.

Choosing a driver model for a file system driver

For help choosing a model for a file system driver, see File System Minifilter Drivers.

Related topics

Kernel-Mode Driver Framework
User-Mode Driver Framework


[0x0003] DEVICE_OBJECT structure

DEVICE_OBJECT structure

The DEVICE_OBJECT structure is used by the operating system to represent a device object. A device object represents a logical, virtual, or physical device for which a driver handles I/O requests.

Syntax

typedef struct _DEVICE_OBJECT {
  CSHORT                      Type;
  USHORT                      Size;
  LONG                        ReferenceCount;
  struct _DRIVER_OBJECT  *DriverObject;
  struct _DEVICE_OBJECT  *NextDevice;
  struct _DEVICE_OBJECT  *AttachedDevice;
  struct _IRP  *CurrentIrp;
  PIO_TIMER                   Timer;
  ULONG                       Flags;
  ULONG                       Characteristics;
  __volatile PVPB             Vpb;
  PVOID                       DeviceExtension;
  DEVICE_TYPE                 DeviceType;
  CCHAR                       StackSize;
  union {
    LIST_ENTRY         ListEntry;
    WAIT_CONTEXT_BLOCK Wcb;
  } Queue;
  ULONG                       AlignmentRequirement;
  KDEVICE_QUEUE               DeviceQueue;
  KDPC                        Dpc;
  ULONG                       ActiveThreadCount;
  PSECURITY_DESCRIPTOR        SecurityDescriptor;
  KEVENT                      DeviceLock;
  USHORT                      SectorSize;
  USHORT                      Spare1;
  struct _DEVOBJ_EXTENSION  *  DeviceObjectExtension;
  PVOID                       Reserved;
} DEVICE_OBJECT, *PDEVICE_OBJECT;

Members

Type
Used by the operating system to indicate that an object is a device object. For device objects, the value of this member is 3. This is a read-only member.
Size
Specifies the size, in bytes, of the device object. This size includes the driver-specified device extension pointed to by the DeviceExtension member, but does not include the opaque device object extension pointed to by the DeviceObjectExtension member. Size is a read-only member.
ReferenceCount
Used by the I/O manager to track the number of open handles for the device that are associated with the device object. This allows the I/O manager to avoid unloading a driver when there are outstanding handles for the driver's device(s). This is a read-only member.
DriverObject
A pointer to the driver object (DRIVER_OBJECT), that represents the loaded image of the driver that was input to the DriverEntry and AddDevice routines. This member is set by the I/O manager upon a successful call to IoCreateDevice or IoCreateDeviceSecure. This is a read-only member.
NextDevice
A pointer to the next device object, if any, that was created by the same driver. The I/O manager updates this list at each successful call to IoCreateDevice or IoCreateDeviceSecure.
A non- Plug and Play (PnP) driver that is being unloaded must traverse ("walk") the list of its device objects and delete them. A PnP driver does not have to walk this list of device objects. Instead, PnP drivers perform their cleanup during the device removal PnP operation (IRP_MN_REMOVE_DEVICE).
A driver that recreates its device objects dynamically also uses this member. This is a read/write member.
AttachedDevice
A pointer to the attached device object. If there is no attached device object, this member is NULL. The device object that is pointed to by the AttachedDevice member typically is the device object of a filter driver, which intercepts I/O requests originally targeted to the device represent by the device object. For more information, see the IoAttachDevice and IoAttachDeviceByPointer topics. This is an opaque member.
CurrentIrp
A pointer to the current IRP if the driver has a StartIo routine whose entry point was set in the driver object and if the driver is currently processing IRP(s). Otherwise, this member is NULL. For more information, see the IoStartPacket and IoStartNextPacket topics. This is a read-only member.
Timer
A pointer to a timer object. This allows the I/O manager to call a driver-supplied timer routine every second. For more information, see IoInitializeTimer. This is a read/write member.
Flags
Device drivers perform a bitwise OR operation with this member in their newly created device objects by using one or more of the following system-defined values:
DO_BUFFERED_IO or DO_DIRECT_IO
Specifies the type of buffering that is used by the I/O manager for I/O requests that are sent to the device stack. Higher-level drivers OR this member with the same value as the next-lower driver in the stack, except possibly for highest-level drivers.
DO_BUS_ENUMERATED_DEVICE
The operating system sets this flag in each physical device object (PDO). Drivers must not modify this flag.
DO_DEVICE_INITIALIZING
The I/O manager sets this flag when it creates the device object. A device function driver or filter driver clears the flag in its AddDevice routine, after it does the following:
  • Attaches the device object to the device stack.
  • Establishes the device power state.
  • Performs a bitwise OR operation on the member with one of the power flags (if it is necessary).
The Plug and Play (PnP) manager checks that the flag is clear after the AddDevice routine returns.
DO_EXCLUSIVE
Indicates that the driver services an exclusive device, such as a video, serial, parallel, or sound device. WDM drivers must not set this flag. For more information, see the Specifying Exclusive Access to Device Objects topic.
DO_MAP_IO_BUFFER
This flag is no longer used. Drivers should not set this flag.
DO_POWER_INRUSH
Drivers of devices that require inrush current when the device is turned on must set this flag. A driver cannot set both this flag and DO_POWER_PAGABLE.
DO_POWER_PAGABLE
Pageable drivers that are compatible with Microsoft Windows 2000 and later versions of Windows, are not part of the paging path, and do not require inrush current must set this flag. The system calls such drivers at IRQL = PASSIVE_LEVEL. Drivers cannot set both this flag and DO_POWER_INRUSH. All drivers for WDM, Microsoft Windows 98, and Windows Millennium Edition must set DO_POWER_PAGABLE.
DO_SHUTDOWN_REGISTERED
Used by the I/O manager to indicate that a driver has registered the device object for shutdown notifications. This flag should not be used by drivers.
DO_VERIFY_VOLUME
Removable-media drivers set this flag while they process transfer requests. Such drivers should also check for this flag in the target for a transfer request before they transfer any data. For more information, see the Supporting Removable Media topic.
For more information about how to set the Flags member, see Initializing a Device Object.
Characteristics
Specifies one or more system-defined constants, combined with a bitwise OR operation, that provide additional information about the driver's device. These constants include the following:
FILE_AUTOGENERATED_DEVICE_NAME
Directs the I/O manager to generate a name for the device, instead of the caller specifying aDeviceName when it calls this routine. The I/O manager makes sure that the name is unique. This characteristic is typically specified by a PnP bus driver to generate a name for a physical device object (PDO) for a child device on the same bus. This characteristic is new starting with Microsoft Windows 2000 and Microsoft Windows 98.
FILE_CHARACTERISTIC_PNP_DEVICE
Indicates that the device object is part of a Plug and Play (PnP) stack. This characteristic is required if a bus driver (or bus filter driver) registers WMI support for a device object that has not yet received the IRP_MN_START_DEVICE request. FILE_CHARACTERISTIC_PNP_DEVICE is also required if a function or filter driver registers for WMI before attaching to its device stack.
FILE_CHARACTERISTIC_TS_DEVICE
Indicates that the device object is part of a Terminal Services device stack. Drivers should not set this characteristic.
FILE_CHARACTERISTIC_WEBDAV_DEVICE
Indicates that a Web-based Distributed Authoring and Versioning (WebDAV) file system is mounted on the device. Drivers should not set this characteristic.
FILE_DEVICE_IS_MOUNTED
Indicates that a file system is mounted on the device. Drivers should not set this characteristic.
FILE_DEVICE_SECURE_OPEN
Directs the I/O manager to apply the security descriptor of the device object to relative opens and trailing file name opens for the device. For more information, see the Controlling Device Namespace Access topic.
FILE_FLOPPY_DISKETTE
Indicates that the device is a floppy disk device.
FILE_READ_ONLY_DEVICE
Indicates that the device cannot be written to.
FILE_REMOTE_DEVICE
Indicates that the device is remote.
FILE_REMOVABLE_MEDIA
Indicates that the storage device supports removable media. Notice that this characteristic indicates removable media, not a removable device. For example, drivers for JAZ drive devices should specify this characteristic, but drivers for PCMCIA flash disks should not.
FILE_VIRTUAL_VOLUME
Indicates that the volume is virtual. Drivers should not set this characteristic.
FILE_WRITE_ONCE_MEDIA
Indicates that the device supports write-once media. Drivers do not set this member directly. For more information about how to set device characteristics, see the Specifying Device Characteristics topic.
FILE_CHARACTERISTIC_CSV
Indicates that the device is a Cluster Shared Volume (CSV).
FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL
The IO Manager normally performs a full security check for traverse access on every file open when the client is an app container. Setting of this flag bypasses this enforced traverse access check if the client token already has traverse privileges.
FILE_PORTABLE_DEVICE
Indicates that the underlying stack considers the device portable. This is used by the storage stack and means that the device is not in the local machine container and is not on a fixed bus type.
Vpb
A pointer to the volume parameter block (VPB) that is associated with the device object. For file system drivers, the VPB can provide a connection to any unnamed logical device object that represents an instance of a mounted volume. This is an opaque member.
DeviceExtension
A pointer to the device extension. The structure and contents of the device extension are driver-defined. The size is driver-determined, specified in the driver's call to IoCreateDevice or IoCreateDeviceSecure. For more information about device extensions, see Device Extensions. This is a read-only member. However, the object that the member points to can be modified by the driver.
DeviceType
Set by IoCreateDevice and IoCreateDeviceSecure by using the value that is specified for that routine'sDeviceType parameter. For more information, see the Specifying Device Types topic.
StackSize
Specifies the minimum number of stack locations in IRPs to be sent to this driver. IoCreateDevice andIoCreateDeviceSecure set this member to 1 in newly created device objects; lowest-level drivers can therefore ignore this member. The I/O manager automatically sets the StackSize member in a higher-level driver's device object to the appropriate value if the driver calls IoAttachDevice orIoAttachDeviceToDeviceStack. Only a higher-level driver that chains itself over another driver withIoGetDeviceObjectPointer must explicitly set the value of StackSize in its own device object(s) to 1 + the StackSize value of the next-lower driver's device object.
Queue
Used internally by the I/O manager to queue the device object when it is required. This is an opaque member.
ListEntry
LIST_ENTRY structure that contains forward and backward pointers for a doubly linked list.
Wcb
Device context information used by I/O manager.
AlignmentRequirement
Specifies the device's address alignment requirement for data transfers. The value must be one of the FILE_XXX_ALIGNMENT values that are defined in Wdm.h. For more information, see the Initializing a Device ObjectGetDmaAlignment, and ZwQueryInformationFile topics.
DeviceQueue
The device queue object for the device object. The device queue object contains any IRPs that are waiting to be processed by the driver that is associated with the device object. For more information, see the Driver-Managed IRP Queues topic. This is an opaque member.
Dpc
The deferred procedure call (DPC) object for the device object. For more information, see theIntroduction to DPC Objects topic. This is an opaque member.
ActiveThreadCount
Reserved for future use. This is an opaque member.
SecurityDescriptor
Specifies a security descriptor (SECURITY_DESCRIPTOR) for the device object when the device object is created. If this member is NULL, the device object receives default security settings. This is a read-only member, although the member can be modified through the ZwSetSecurityObjectfunction.
DeviceLock
A synchronization event object that is allocated by the I/O manager. The I/O manager obtains his event object before it dispatches a mount or mount-verify request to a file-system driver. This is an opaque member.
SectorSize
If the device object does not represent a volume, this member is set to zero. If the device object represents a volume, this member specifies the volume's sector size, in bytes. The I/O manager uses this member to make sure that all read operations, write operations, and set file position operations that are issued are aligned correctly when intermediate buffering is disabled. A default system bytes-per-sector value is used when the device object is created, however, file system drivers; and more rarely, legacy and minifilter drivers, can update this value that is based on the geometry of the underlying volume hardware when a mount occurs. Other drivers should not modify this member.
Spare1
Reserved for system use. This is an opaque member.
DeviceObjectExtension
A pointer to a device object extension that is used by the I/O manager and PnP manager to store information about the state of the device. This is an opaque member.
Reserved
Reserved for system use. This is an opaque member.

Remarks

The operating system represents devices by device objects. For more information, see the Device Objects and Device Stacks topic.
Drivers create device objects by using the IoCreateDevice and IoCreateDeviceSecure routines. For more information about how to create device objects, see Creating a Device Object.
A device object is partially opaque. Drivers do not set members of the device object directly, unless otherwise documented. For more information about the members that drivers can modify directly, see Initializing a Device Object. For information about other device object properties, see Properties of Device Objects.
Opaque members within a device object must be considered inaccessible. Drivers that have dependencies on object member locations or access to opaque members might not remain portable and interoperable with other drivers over time.
The system-supplied video port driver sets up the fields of the device objects that it creates on behalf of video miniport drivers.
The system-supplied SCSI port driver sets up the fields of the device objects that it creates on behalf of SCSI miniport drivers.
The system-supplied NDIS library sets up the fields of the device objects that it creates on behalf of NDIS miniport drivers.

Requirements

Header
Wdm.h (include Wdm.h, Ntddk.h, Ntifs.h, or Fltkernel.h)

See also

DRIVER_OBJECT
IoAttachDevice
IoAttachDeviceToDeviceStack
IoCreateDevice
IoDeleteDevice
IoGetDeviceObjectPointer