NTSTATUS ClaimResources(IN PDEVICE_OBJECT phddo) {
PPHDIO_DEVICE_EXTENSION dx = (PPHDIO_DEVICE_EXTENSION)phddo->DeviceExtension;
// Get resource count: either 1 (IOport) or 2 (IOport&IRQ)
ULONG PartialResourceCount = 1;
if (dx->GotInterrupt) PartialResourceCount++;
// Get size of required CM_RESOURCE_LIST
ULONG ListSize = FIELD_OFFSET(CM_RESOURCE_LIST, List[0]);
ListSize += sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + ((PartialResourceCount-1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
// Allocate CM_RESOURCE_LIST
PCM_RESOURCE_LIST ResourceList = (PCM_RESOURCE_LIST)ExAllocatePool(PagedPool, ListSize);
if (ResourceList==NULL) {
DebugPrintMsg('Cannot allocate memory for ResourceList');
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(ResourceList, ListSize);
// Only one Full Resource Descriptor needed, for ISA
ResourceList->Count = 1;
// Initialise Full Resource Descriptor
PCM_FULL_RESOURCE_DESCRIPTOR FullRD = &ResourceList->List[0];
FullRD->InterfaceType = Isa;
FullRD->BusNumber = 0;
FullRD->PartialResourceList.Count = PartialResourceCount;
// Initialise Partial Resource Descriptor for IO port
PCM_PARTIAL_RESOURCE_DESCRIPTOR resource = &FullRD->PartialResourceList.PartialDescriptors[0];
resource->Type = CmResourceTypePort;
resource->ShareDisposition = CmResourceShareDriverExciusive;
resource->Flags = CM_RESOURCE_PORT_IO;
resource->u.Port.Start = dx->PortStartAddress;
resource->u.Port.Length = dx->PortLength;
// Initialise Partial Resource Descriptor for Interrupt
if (dx->GotInterrupt) {
resource++;
resource->Type = CmResourceTypeInterrupt;
resource->ShareDisposition = CmResourceShareDriverExclusive;
if (dx->Mode==Latched) resource->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
else resource->F1ags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
resource->u.Interrupt.Level = dx->Irql;
resource->u.Interrupt.Vector = dx->Irql;
resource->u.Interrupt.Affinity = 1;
}
// Ask for resources for the driver
DebugPrint('Allocating %d resources', PartialResourceCount);
DebugPrint('phddo->DriverObject %x', phddo->DriverObject);
if (dx->ResourceOverride) DebugPrintMsg('Resource override conflict');
BOOLEAN ConflictDetected;
NTSTATUS status = IoReportResourceUsage(NULL,
phddo->DriverObject, ResourceList, ListSize, // Driver resources
NULL, NULL, 0, // Device resources
dx->ResourceOverride, &ConflictDetected);
// Cope (or override) if resource conflict found
if (ConflictDetected) {
DebugPrintMsg('ConflictDetected');
if (dx->ResourceOverride) {
DebugPrintMsg('Conflict detected and overridden');
status = STATUS_SUCCESS;
}
}
// Free allocated memory
ExFreePool(ResourceList);
return status;
}
Table 18.1 shows the parameters for
In the NT and Windows 2000 platforms, the resource assignments end up in the registry in the HKLMHARDWARERESOURCEMAP key[45]. If you specify a DriverClassName parameter, this string is used as a subkey to hold the resource assignments. Otherwise, in NT 4 and NT 3.51, the resource assignments end up in the 'OtherDrivers' subkey. In W2000, the resource assignments are in the 'PnP Manager' subkey. You can use
Table 18.1 IoReportResourceUsage function
NTSTATUS IoReportResourceUsage | (IRQL==PASSIVE_LEVEL) |
---|---|
Parameter | Description |
IN PUNICODE_STRING DriverClassName | Optional resource class name |
IN PDRIVER_OBJECT DriverObject | Driver object pointer |