}

 }

 return status;

}

NTSTATUS AbcConfigCallback(IN PVOID Context, IN PUNICODE_STRING PathName, IN INTERFACE_TYPE BusType, IN ULONG BusNumber, IN PKEY_VALUE_FULL_INFORMATION *BusInfo, IN CONFIGURATION_TYPE CtrlrType, IN ULONG CtrlrNumber, IN PKEY_VALUE_FULL_INFORMATION *CtrlrInfo, IN CONFIGURATION_TYPE Peripheral Type, IN ULONG Peripheral Number, IN PKEY_VALUE_FULL_INFORMATION *PeripheralInfo) {

 DebugPrint('ConfigCallback: Bus: %d,%d', BusType, BusNumber);

 DebugPrint('ConfigCallback: Controller: %d,%d', CtrlrType, CtrlrNumber);

 DebugPrint('ConfigCallback: Peripheral: %d,%d', PeripheralType, PeripheralNumber);

 if (CtrlrInfo!=NULL) {

  PCM_FULL_RESOURCE_DESCRIPTOR frd =

   (PCM_FULL_RESOURCE_DESCRIPTOR) (((PUCHAR)CtrlrInfo[IoQueryDeviceConfigurationData]) +

   CtrlrInfo[IoQueryDeviceConfigurationData]->DataOffset);

  for (ULONG i=0; i<frd->PartialResourceList.Count; i++) {

   PCM_PARTIAL_RESOURCE_DESCRIPTOR resource = &frd->PartialResourceList.PartialDescriptors[i];

   switch(resource->Type) {

   case CmResourceTypePort:

    DebugPrint('ConfigCallback: I/O port %x,%d', resource->u.Port.Start.LowPart, resource->u.Port.Length);

    break;

   case CmResourceTypeInterrupt:

    DebugPrint('ConfigCallback: Interrupt level %c vector %d', resource->u.Interrupt.Level, resource->u.Interrupt.Vector);

    break;

   default:

    DebugPrint('ConfigCallback: Resource type %d', resource->Type);

   }

  }

 }

 return STATUS_SUCCESS;

}

Interrogating Configurable Buses

A configurable bus is one that can be configured in software. Devices on these buses must have Plug and Play WDM device drivers. The PCI bus driver will retrieve a device's details and generate an appropriate Hardware ID. This Hardware ID will be used to identify the correct driver. Its AddDevice routine is called, etc.

In NT systems, you will need to use a different technique to get configurable bus data. This method still works in Windows 2000. The HalGetBusData and HalGetBusDataByOffset calls can be made to retrieve configuration data for one slot of a specified bus instance. For example, if you ask for PCIConfiguration bus data, the passed buffer is filled with PCI_COMMON_CONFIG data.

You can then claim the necessary resources using IoAssignResources, in a similar way to IoReportResourceUsage. As an alternative, drivers of PCI-type devices can call HalAssignSlotResources. HalSetBusData and HalSetBusDataByOffset can be used to write back configuration data.

I have not tried it, but it looks as though HalGetBusData and HalSetBusData can be used to access the BIOS CMOS data.

Final Resource Discovery Techniques

There are two final ways of obtaining a driver's resource requirements. The first is to store the relevant information in the driver's registry key, say in its Parameters subkey. This information will typically be set up when the device is installed.

Last and least, you can simply poke around in likely memory locations to see if your device is present. Dangerous.

Conclusion

This chapter has looked at how to write an NT style device driver such as PHDIo. As it does not use Plug and Play, it must use different techniques to find what hardware resources it needs, reserve them, and translate them into usable values.

The PHDIo driver receives its resource details for its controlling Win32 application. Other drivers must find out what devices the kernel has found or interrogate all the configurable buses itself.

Chapter 19

WDM System Drivers

This chapter serves as a brief introduction to the system drivers that are provided as a part of the Windows Driver Model (WDM). These bus and class drivers are a very important part of the model. You can and should use the relevant system driver to access standard types of bus. These bus drivers are sometimes called class drivers, as they let you talk to a whole class of devices.

Figure 19.1 shows the main system drivers. Chapter 2 gave a brief overview of each of these. The remaining chapters of this book look in detail at the Universal Serial Bus (USB) and Human Input Device (HID) class drivers.

Figure 19.1 WDM system drivers

Writing Client Drivers

Each type of system driver has its own documentation that you must consult. In many cases, there will be a specification provided by a major standards body and a further specification provided by Microsoft for its system driver. For example, the core USB specification is produced jointly by Compaq, Intel, Microsoft, and NEC. However, the Windows USB Driver Interface (USBDI) is solely Microsoft's responsibility.

There are two main ways to work with system drivers. The first, a client, is when you use the system drivers to access your device. The second driver category interfaces the system to your hardware, by writing a minidriver, a miniclass driver, or a miniport driver. This book does not cover this last type of driver.

If you are writing a client driver, you need to understand and use the core WDM driver technologies as well as all the system driver's capabilities. This usually means that you must write a Plug and Play device driver with Power Management and Windows Management Instrumentation capabilities. Although this seems like an onerous task, the provision of standard system drivers definitely makes your task easier. To help you further, for the USB and HID cases, you can base your driver on the examples given in the rest of this book.

There are two main types of client driver that you can write[46]. The first is when you use a standard Plug and Play (PnP) INF file to make yourself part of the driver stack for a particular device, as all the WDM drivers in this book have done so far. The second type of client is an NT style driver that uses PnP Notification. Such a driver is notified when a device of the right type arrives. Your client can then make its own device object to represent the underlying device. The USB and HID drivers in the rest of this book illustrate how to write both types of client.

Common Devices

Occasionally you may want to control the behavior of all your devices. Rather than find each device and send IOCTLs to each one, a useful technique is to provide an additional 'common device' that can be used to control the features that are common to all the other devices.

This common device object is typically an NT style device object created in your DriverEntry routine with a fixed symbolic link name. Your control application would open a handle to this common device, and, for example, use some IOCTLs to change the general behavior of your driver.

The complication to this approach is that your IRP dispatch routines will receive requests both for your ordinary devices and for your common device. Control requests for the ordinary devices should be rejected, and vice versa. The simplest way to achieve this functionality is to have a flag in the device extension that indicates the device type. You could have two separate device extensions, with the device type flag in a common portion of each structure.

Filter Drivers

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату
×