Listing 18.2 PHDIoCreate routine

NTSTATUS PHDIoCreate(IN PDEVICE_OBJECT phddo, IN PIRP Irp) {

 PPHDIO_DEVICE_EXTENSION dx = (PPHDIO_DEVICE_EXTENSION)phddo->DeviceExtension;

 PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);

 DebugPrint('Create File is %T', &(IrpStack->FileObject->FileName));

 dx->GotPortOrMemory = false;

 dx->GotInterrupt = false;

 dx->PortNeedsMapping = false;

 dx->ConnectedToInterrupt = false;

 dx->ResourceOverride = FALSE;

 // Get resources from filename string

 PUNICODE_STRING usfilename = &(IrpStack->FileObject->FileName);

 NTSTATUS status = *(usfilename,dx);

 if (!NT_SUCCESS(status)) goto fail;

 // We must have IO port resource

 if (!dx->GotPortOrMemory) {

  DebugPrintMsg('No IO Port resource in filename');

  status = STATUS_INVALID_PARAMETER:

  goto fail;

 }

 // Claim resources

 status = ClaimResources(phddo);

 if (!NT_SUCCESS(status)) {

  DebugPrintMsg('Could not ClaimResources');

  goto fail;

 }

 // Translate and map resources

 status = TranslateAndMapResources(phddo);

 if (!NT_SUCCESS(status)) {

  UnclaimResources(phddo);

  goto fail;

 }

 // Complete

 return CompleteIrp(Irp,status);

 // On error, make sure everything's off fail:

 dx->GotPortOrMemory = false;

 dx->GotInterrupt = false;

 dx->PortNeedsMapping = false;

 dx->ConnectedToInterrupt = false;

 return CompleteIrp(Irp,status);

}

Claiming resources means working with Full and Partial Resource Descriptors. Chapter 9 showed that a device's resource assignments are given in these structures when the Plug and Play Start Device is received. The WdmIo driver obtains its resource assignments in this way.

NT style drivers have to build a resource list of these descriptors to pass to the IoReportResourceUsage routine. Note carefully that the raw resource details must be passed to IoReportResourceUsage, not the translated values. The kernel resource list structures are sufficiently intricate that it is worth showing them in Listing 1 8.3.

A resource list consists of one Full Resource Descriptor for each bus instance. Note carefully that this is an expandable structure. Although it is declared with only one Full Resource Descriptor, it may in fact contain one or more such descriptors.

A Full Resource Descriptor specifies the bus type and instance number. It also contains a Partial Resource List structure.

A Partial Resource List primarily contains an array of Partial Resource Descriptors. Again, note that a Partial Resource List is a structure that expands as more Partial Resource Descriptors are used.

A Partial Resource Descriptor finally contains the details of an individual resource. Table 9.2 in Chapter 9 gives full details of Partial Resource Descriptors.

Listing 18.3 Kernel resource list structures

typedef struct _CM_RESOURCE_LIST {

 ULONG Count;

 CM_FULL_RESOURCE_DESCRIPTOR List[1];

} CM_RESOURCE_LIST, *PCM_RESOURCE_LIST;

typedef struct _CM_FULL_RESOURCE_DESCRIPTOR {

 INTERFACE_TYPE InterfaceType; // unused for WDM

 ULONG BusNumber; // unused for WDM

 CM_PARTIAL_RESOURCE_LIST PartialResourceList;

} CM_FULL_RESOURCE_DESCRIPTOR, *PCM_FULL_RESOURCE_DESCRIPTOR;

typedef struct _CM_PARTIAL_RESOURCE_LIST {

 USHORT Version;

 USHORT Revision;

 ULONG Count;

 CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1];

} CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST;

typedef struct _CM_PARTIAL_RESOURCE_DESCRIPTOR {

 UCHAR Type;

 UCHAR ShareDisposition;

 USHORT Flags;

 union {

  // …

 } u;

} CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR;

The PHDIo driver deals with only the first instance of the ISA bus, so it needs only one Full Resource Descriptor. It always has one Partial Resource Descriptor for the I/O port. It can also have a second Partial Resource Descriptor for the interrupt, if one was specified.

ClaimResources, in Listing 18.4, builds a resource list structure and passes it to IoReportResourceUsage.

As you can guess, it is quite a job building the resource list correctly. The correct size for the whole structure must be determined first. A suitably sized block of paged memory is allocated and zeroed.

ClaimResources gradually fills the resource list. The resource list Count is set to one, as there is only one Full Resource Descriptor. The Full Resource Descriptor InterfaceType field is set to Isa and the BusNumber is set to 0. The Partial Resource List Count is set to 1 or 2, depending on how many resources are declared. The Partial Resource Descriptor for the I/O port is generated, then the one for the interrupt, if required. Whew!

There is a final complication to calling IoReportResourceUsage. You must either specify the resource list as belonging to the whole driver, or associate the resource list with an individual device. PHDIo says that the resources belong to the whole driver. If PHDIo were enhanced to provide more than one device, it would make sense to allocate resources on a per- device basis. One call to IoReportResourceUsage per device would be needed in this case.

Listing 18.4 ClaimResources routine

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

0

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

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