Exemple #1
0
PIO_RESOURCE_REQUIREMENTS_LIST
IopAddDefaultResourceList (
    IN PIO_RESOURCE_REQUIREMENTS_LIST IoResourceList,
    IN PCM_RESOURCE_LIST CmResourceList
)
/*++

Routine Description:

    This functions builds an IO resource list by adjusting input IoResourceList to
    the ranges specified by CmResourceList and merges the new Io resource list to the
    input IoResourceList and returns the combined list.
    If IoResourceList has zero descriptor, this routine bulds an
    IO RESOURCE REQUIREMENTS LIST by simply converting the CmResourceList.
    It's caller's responsiblity to free the returned list.

Arguments:

    IoResourceList - The resource requirements list which needs to
                     be adjusted.

    CmResourceList - the cm resource list to specify the resource ranges desired.

Return Value:

    returns a IO_RESOURCE_REQUIREMENTS_LISTST if succeeds.  Otherwise a NULL value is
    returned.

--*/
{
    PIO_RESOURCE_REQUIREMENTS_LIST ioResReqList, combinedList = NULL;
    SUPPORTED_RANGES supportRanges;
    SUPPORTED_RANGE interruptRange;
    PSUPPORTED_RANGE range, tmpRange;
    PSUPPORTED_RANGE intRange = NULL, ioRange = NULL, memRange = NULL, dmaRange = NULL;
    ULONG size, i, j, addressSpace = 0;
    PCM_FULL_RESOURCE_DESCRIPTOR cmFullDesc;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR cmPartDesc;
    NTSTATUS status;

    if (!IoResourceList) {

        //
        // If IoResourceList is NULL, return failure.
        //

        return NULL;
    } else if (IoResourceList->List[0].Count == 0) {

        //
        // an empty Io resource requirements list, simply return the converted
        // list.
        //

        ioResReqList = IopCmResourcesToIoResources(IoResourceList->SlotNumber,
                       CmResourceList);
        return ioResReqList;
    }

    //
    // Clip the IoResourceList against CmResourceList.
    // First, build the supported ranges structure to do the clipping.
    //

    RtlZeroMemory(&supportRanges, sizeof(supportRanges));
    supportRanges.Version = BUS_SUPPORTED_RANGE_VERSION;
    supportRanges.Sorted = FALSE;
    ioResReqList = NULL;

    cmFullDesc = &CmResourceList->List[0];
    for (i = 0; i < CmResourceList->Count; i++) {
        cmPartDesc = &cmFullDesc->PartialResourceList.PartialDescriptors[0];
        for (j = 0; j < cmFullDesc->PartialResourceList.Count; j++) {
            size = 0;
            range = NULL;
            switch (cmPartDesc->Type) {
            case CmResourceTypePort:
                if (!ioRange) {
                    range = &supportRanges.IO;
                } else {
                    range = (PSUPPORTED_RANGE)ExAllocatePool(PagedPool, sizeof(SUPPORTED_RANGE));
                    ioRange->Next = range;
                }
                range->SystemAddressSpace = 1;
                range->SystemBase = 0;
                range->Base = cmPartDesc->u.Port.Start.QuadPart;
                range->Limit = cmPartDesc->u.Port.Start.QuadPart +
                               cmPartDesc->u.Port.Length - 1;
                range->Next = NULL;
                ioRange = range;
                supportRanges.NoIO++;
                break;
            case CmResourceTypeInterrupt:
                if (!intRange) {
                    range = &interruptRange;
                } else {
                    range = (PSUPPORTED_RANGE)ExAllocatePool(PagedPool, sizeof(SUPPORTED_RANGE));
                    intRange->Next = range;
                }
                range->SystemAddressSpace = 0;
                range->SystemBase = 0;
                range->Base = cmPartDesc->u.Interrupt.Vector;
                range->Limit = cmPartDesc->u.Interrupt.Vector;
                range->Next = NULL;
                intRange = range;
                break;
            case CmResourceTypeMemory:
                if (!memRange) {
                    range = &supportRanges.Memory;
                } else {
                    range = (PSUPPORTED_RANGE)ExAllocatePool(PagedPool, sizeof(SUPPORTED_RANGE));
                    memRange->Next = range;
                }
                range->SystemAddressSpace = 0;
                range->SystemBase = 0;
                range->Base = cmPartDesc->u.Memory.Start.QuadPart;
                range->Limit = cmPartDesc->u.Memory.Start.QuadPart +
                               cmPartDesc->u.Memory.Length - 1;
                range->Next = NULL;
                memRange = range;
                supportRanges.NoMemory++;
                break;
            case CmResourceTypeDma:
                if (!dmaRange) {
                    range = &supportRanges.Dma;
                } else {
                    range = (PSUPPORTED_RANGE)ExAllocatePool(PagedPool, sizeof(SUPPORTED_RANGE));
                    dmaRange->Next = range;
                }
                range->SystemAddressSpace = 0;
                range->SystemBase = 0;
                range->Base = cmPartDesc->u.Dma.Channel;
                range->Limit = cmPartDesc->u.Dma.Channel;
                range->Next = NULL;
                dmaRange = range;
                supportRanges.NoDma++;
                break;
            case CmResourceTypeDeviceSpecific:
                size = cmPartDesc->u.DeviceSpecificData.DataSize;
                break;
            }
            cmPartDesc++;
            cmPartDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmPartDesc + size);
        }
        cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmPartDesc;
    }

    //
    // Adjust the input resource requirements list ...
    //

    status = IopAdjustResourceListRange (
                 &supportRanges,
                 &interruptRange,
                 IoResourceList,
                 &ioResReqList
             );

    if (!NT_SUCCESS(status)) {
        goto exit0;
    }

    //
    // Combine the clipped io resource requirements list with the original resource
    // list.
    //

    size = ioResReqList->ListSize + IoResourceList->ListSize -
           FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List);
    combinedList = (PIO_RESOURCE_REQUIREMENTS_LIST) ExAllocatePool(PagedPool, size);
    if (combinedList) {
        RtlMoveMemory(combinedList, ioResReqList, ioResReqList->ListSize);
        combinedList->ListSize = size;
        combinedList->AlternativeLists += IoResourceList->AlternativeLists;
        RtlMoveMemory((PUCHAR)combinedList + ioResReqList->ListSize,
                      (PUCHAR)IoResourceList->List,
                      IoResourceList->ListSize - FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List)
                     );
    }
    ExFreePool(ioResReqList);
exit0:

    //
    // Release the space allocated for supported ranges...
    //

    range = interruptRange.Next;
    while (range) {
        tmpRange = range;
        range = range->Next;
        ExFreePool(tmpRange);
    }
    range = supportRanges.IO.Next;
    while (range) {
        tmpRange = range;
        range = range->Next;
        ExFreePool(tmpRange);
    }
    range = supportRanges.Memory.Next;
    while (range) {
        tmpRange = range;
        range = range->Next;
        ExFreePool(tmpRange);
    }
    range = supportRanges.Dma.Next;
    while (range) {
        tmpRange = range;
        range = range->Next;
        ExFreePool(tmpRange);
    }
    return combinedList;
}
Exemple #2
0
NTSTATUS
IoReportResourceUsageInternal(
    IN ARBITER_REQUEST_SOURCE AllocationType,
    IN PUNICODE_STRING DriverClassName OPTIONAL,
    IN PDRIVER_OBJECT DriverObject,
    IN PCM_RESOURCE_LIST DriverList OPTIONAL,
    IN ULONG DriverListSize OPTIONAL,
    IN PDEVICE_OBJECT DeviceObject OPTIONAL,
    IN PCM_RESOURCE_LIST DeviceList OPTIONAL,
    IN ULONG DeviceListSize OPTIONAL,
    IN BOOLEAN OverrideConflict,
    OUT PBOOLEAN ConflictDetected
    )

/*++

Routine Description:

    This internal routine will do all the work for IoReportResourceUsage.

Arguments:

    AllocationType - Specifies the request type.

    DriverClassName - Optional pointer to a UNICODE_STRING which describes
        the class of driver under which the driver information should be
        stored. A default type is used if none is given.

    DriverObject - Pointer to the driver's driver object.

    DriverList - Optional pointer to the driver's resource list.

    DriverListSize - Optional value determining the size of the driver's
        resource list.

    DeviceObject - Optional pointer to driver's device object.

    DeviceList - Optional pointer to the device's resource list.

    DriverListSize - Optional value determining the size of the driver's
        resource list.

    OverrideConflict - Determines if the information should be reported
        in the configuration registry eventhough a conflict was found with
        another driver or device.

    ConflictDetected - Supplies a pointer to a boolean that is set to TRUE
        if the resource list conflicts with an already existing resource
        list in the configuration registry.

Return Value:

    The status returned is the final completion status of the operation.

--*/

{
    NTSTATUS                        status = STATUS_UNSUCCESSFUL;
    PCM_RESOURCE_LIST               resourceList;
    PCM_RESOURCE_LIST               allocatedResources;
    PIO_RESOURCE_REQUIREMENTS_LIST  resourceRequirements;
    ULONG                           attempt;
    BOOLEAN                         freeAllocatedResources;

    ASSERT(DriverObject && ConflictDetected);

    if (DeviceList) {

        resourceList = DeviceList;

    } else if (DriverList) {

        resourceList = DriverList;

    } else {

        resourceList = NULL;

    }

    resourceRequirements = NULL;

    if (resourceList) {

        if (resourceList->Count && resourceList->List[0].PartialResourceList.Count) {

            resourceRequirements = IopCmResourcesToIoResources (0, resourceList, LCPRI_NORMAL);

            if (resourceRequirements == NULL) {

                return status;

            }

        } else {

            resourceList = NULL;

        }

    }

    *ConflictDetected = TRUE;
    attempt = 0;
    allocatedResources = resourceList;
    freeAllocatedResources = FALSE;
    do {

        //
        // Do the legacy resource allocation.
        //

        status = IopLegacyResourceAllocation (  AllocationType,
                                                DriverObject,
                                                DeviceObject,
                                                resourceRequirements,
                                                &allocatedResources);

        if (NT_SUCCESS(status)) {

            *ConflictDetected = FALSE;
            break;
        }

        //
        // Change the interface type and try again.
        //

        if (!IopChangeInterfaceType(resourceRequirements, &allocatedResources)) {

            break;
        }
        freeAllocatedResources = TRUE;

    } while (++attempt < 2);

    if (resourceRequirements) {

        ExFreePool(resourceRequirements);

    }

    if (freeAllocatedResources) {

        ExFreePool(allocatedResources);
    }

    if (NT_SUCCESS(status)) {

        status = STATUS_SUCCESS;

    } else {

        status = STATUS_INSUFFICIENT_RESOURCES;

    }

    return status;
}