static BOOLEAN IopCheckDescriptorForConflict(PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc, OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor) { CM_RESOURCE_LIST CmList; NTSTATUS Status; CmList.Count = 1; CmList.List[0].InterfaceType = InterfaceTypeUndefined; CmList.List[0].BusNumber = 0; CmList.List[0].PartialResourceList.Version = 1; CmList.List[0].PartialResourceList.Revision = 1; CmList.List[0].PartialResourceList.Count = 1; CmList.List[0].PartialResourceList.PartialDescriptors[0] = *CmDesc; Status = IopDetectResourceConflict(&CmList, TRUE, ConflictingDescriptor); if (Status == STATUS_CONFLICTING_ADDRESSES) return TRUE; return FALSE; }
NTSTATUS NTAPI IopAssignDeviceResources( IN PDEVICE_NODE DeviceNode) { NTSTATUS Status; ULONG ListSize; IopDeviceNodeSetFlag(DeviceNode, DNF_ASSIGNING_RESOURCES); Status = IopFilterResourceRequirements(DeviceNode); if (!NT_SUCCESS(Status)) goto ByeBye; if (!DeviceNode->BootResources && !DeviceNode->ResourceRequirements) { DeviceNode->Flags |= DNF_NO_RESOURCE_REQUIRED; DeviceNode->Flags &= ~DNF_ASSIGNING_RESOURCES; /* No resource needed for this device */ DeviceNode->ResourceList = NULL; DeviceNode->ResourceListTranslated = NULL; return STATUS_SUCCESS; } if (DeviceNode->BootResources) { ListSize = PnpDetermineResourceListSize(DeviceNode->BootResources); DeviceNode->ResourceList = ExAllocatePool(PagedPool, ListSize); if (!DeviceNode->ResourceList) { Status = STATUS_NO_MEMORY; goto ByeBye; } RtlCopyMemory(DeviceNode->ResourceList, DeviceNode->BootResources, ListSize); Status = IopDetectResourceConflict(DeviceNode->ResourceList, FALSE, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Boot resources for %wZ cause a resource conflict!\n", &DeviceNode->InstancePath); ExFreePool(DeviceNode->ResourceList); DeviceNode->ResourceList = NULL; } } else { /* We'll make this from the requirements */ DeviceNode->ResourceList = NULL; } /* No resources requirements */ if (!DeviceNode->ResourceRequirements) goto Finish; /* Call HAL to fixup our resource requirements list */ HalAdjustResourceList(&DeviceNode->ResourceRequirements); /* Add resource requirements that aren't in the list we already got */ Status = IopFixupResourceListWithRequirements(DeviceNode->ResourceRequirements, &DeviceNode->ResourceList); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to fixup a resource list from supplied resources for %wZ\n", &DeviceNode->InstancePath); DeviceNode->Problem = CM_PROB_NORMAL_CONFLICT; goto ByeBye; } /* IopFixupResourceListWithRequirements should NEVER give us a conflicting list */ ASSERT(IopDetectResourceConflict(DeviceNode->ResourceList, FALSE, NULL) != STATUS_CONFLICTING_ADDRESSES); Finish: Status = IopTranslateDeviceResources(DeviceNode); if (!NT_SUCCESS(Status)) { DeviceNode->Problem = CM_PROB_TRANSLATION_FAILED; DPRINT1("Failed to translate resources for %wZ\n", &DeviceNode->InstancePath); goto ByeBye; } Status = IopUpdateResourceMapForPnPDevice(DeviceNode); if (!NT_SUCCESS(Status)) goto ByeBye; Status = IopUpdateControlKeyWithResources(DeviceNode); if (!NT_SUCCESS(Status)) goto ByeBye; IopDeviceNodeSetFlag(DeviceNode, DNF_RESOURCE_ASSIGNED); IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES); return STATUS_SUCCESS; ByeBye: if (DeviceNode->ResourceList) { ExFreePool(DeviceNode->ResourceList); DeviceNode->ResourceList = NULL; } DeviceNode->ResourceListTranslated = NULL; IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES); return Status; }
/* * @halfplemented */ NTSTATUS NTAPI IoReportResourceUsage(PUNICODE_STRING DriverClassName, PDRIVER_OBJECT DriverObject, PCM_RESOURCE_LIST DriverList, ULONG DriverListSize, PDEVICE_OBJECT DeviceObject, PCM_RESOURCE_LIST DeviceList, ULONG DeviceListSize, BOOLEAN OverrideConflict, PBOOLEAN ConflictDetected) /* * FUNCTION: Reports hardware resources in the * \Registry\Machine\Hardware\ResourceMap tree, so that a subsequently * loaded driver cannot attempt to use the same resources. * ARGUMENTS: * DriverClassName - The class of driver under which the resource * information should be stored. * DriverObject - The driver object that was input to the * DriverEntry. * DriverList - Resources that claimed for the driver rather than * per-device. * DriverListSize - Size in bytes of the DriverList. * DeviceObject - The device object for which resources should be * claimed. * DeviceList - List of resources which should be claimed for the * device. * DeviceListSize - Size of the per-device resource list in bytes. * OverrideConflict - True if the resources should be cliamed * even if a conflict is found. * ConflictDetected - Points to a variable that receives TRUE if * a conflict is detected with another driver. */ { NTSTATUS Status; PCM_RESOURCE_LIST ResourceList; DPRINT1("IoReportResourceUsage is halfplemented!\n"); if (!DriverList && !DeviceList) return STATUS_INVALID_PARAMETER; if (DeviceList) ResourceList = DeviceList; else ResourceList = DriverList; Status = IopDetectResourceConflict(ResourceList, FALSE, NULL); if (Status == STATUS_CONFLICTING_ADDRESSES) { *ConflictDetected = TRUE; if (!OverrideConflict) { DPRINT1("Denying an attempt to claim resources currently in use by another device!\n"); return STATUS_CONFLICTING_ADDRESSES; } else { DPRINT1("Proceeding with conflicting resources\n"); } } else if (!NT_SUCCESS(Status)) { return Status; } /* TODO: Claim resources in registry */ *ConflictDetected = FALSE; return STATUS_SUCCESS; }