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
NT style drivers have to build a resource list of these descriptors to pass to the
A
A
A
A
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
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
There is a final complication to calling
Listing 18.4 ClaimResources routine