mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 08:52:57 +00:00
If boot resources are provided, use them instead of using resource requirements.
In all cases, translate the resource list before calling the driver svn path=/trunk/; revision=24217
This commit is contained in:
parent
364cdf1951
commit
d2241f8ec4
1 changed files with 340 additions and 166 deletions
|
@ -132,12 +132,6 @@ IopStartDevice(
|
||||||
Stack.Parameters.StartDevice.AllocatedResources = DeviceNode->ResourceList;
|
Stack.Parameters.StartDevice.AllocatedResources = DeviceNode->ResourceList;
|
||||||
Stack.Parameters.StartDevice.AllocatedResourcesTranslated = DeviceNode->ResourceListTranslated;
|
Stack.Parameters.StartDevice.AllocatedResourcesTranslated = DeviceNode->ResourceListTranslated;
|
||||||
|
|
||||||
/* FIXME: Not sure of this! */
|
|
||||||
if (!Stack.Parameters.StartDevice.AllocatedResources)
|
|
||||||
Stack.Parameters.StartDevice.AllocatedResources = DeviceNode->BootResources;
|
|
||||||
if (!Stack.Parameters.StartDevice.AllocatedResourcesTranslated)
|
|
||||||
Stack.Parameters.StartDevice.AllocatedResourcesTranslated = DeviceNode->BootResources;
|
|
||||||
|
|
||||||
Status = IopInitiatePnpIrp(
|
Status = IopInitiatePnpIrp(
|
||||||
Fdo,
|
Fdo,
|
||||||
&IoStatusBlock,
|
&IoStatusBlock,
|
||||||
|
@ -1229,30 +1223,70 @@ IopSetDeviceInstanceData(HANDLE InstanceKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
static NTSTATUS
|
||||||
IopAssignDeviceResources(PDEVICE_NODE DeviceNode)
|
IopAssignDeviceResources(
|
||||||
|
IN PDEVICE_NODE DeviceNode,
|
||||||
|
OUT ULONG *pRequiredSize)
|
||||||
{
|
{
|
||||||
PIO_RESOURCE_LIST ResourceList;
|
PIO_RESOURCE_LIST ResourceList;
|
||||||
PIO_RESOURCE_DESCRIPTOR ResourceDescriptor;
|
PIO_RESOURCE_DESCRIPTOR ResourceDescriptor;
|
||||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorRaw, DescriptorTranslated;
|
PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorRaw;
|
||||||
|
PCM_PARTIAL_RESOURCE_LIST pPartialResourceList;
|
||||||
ULONG NumberOfResources = 0;
|
ULONG NumberOfResources = 0;
|
||||||
ULONG i;
|
ULONG Size;
|
||||||
|
ULONG i, j;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* Fill DeviceNode->ResourceList and DeviceNode->ResourceListTranslated;
|
if (!DeviceNode->BootResources && !DeviceNode->ResourceRequirements)
|
||||||
* by using DeviceNode->ResourceRequirements */
|
|
||||||
|
|
||||||
if (!DeviceNode->ResourceRequirements
|
|
||||||
|| DeviceNode->ResourceRequirements->AlternativeLists == 0)
|
|
||||||
{
|
{
|
||||||
DeviceNode->ResourceList = DeviceNode->ResourceListTranslated = NULL;
|
/* No resource needed for this device */
|
||||||
|
DeviceNode->ResourceList = NULL;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fill DeviceNode->ResourceList
|
||||||
|
* FIXME: the PnP arbiter should go there!
|
||||||
|
* Actually, use the BootResources if provided, else the resource list #0
|
||||||
|
*/
|
||||||
|
|
||||||
|
IopDeviceNodeSetFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
|
||||||
|
|
||||||
|
if (DeviceNode->BootResources)
|
||||||
|
{
|
||||||
|
/* Browse the boot resources to know if we have some custom structures */
|
||||||
|
Size = FIELD_OFFSET(CM_RESOURCE_LIST, List);
|
||||||
|
for (i = 0; i < DeviceNode->BootResources->Count; i++)
|
||||||
|
{
|
||||||
|
pPartialResourceList = &DeviceNode->BootResources->List[i].PartialResourceList;
|
||||||
|
if (pPartialResourceList->Version != 1 || pPartialResourceList->Revision != 1)
|
||||||
|
{
|
||||||
|
Status = STATUS_REVISION_MISMATCH;
|
||||||
|
goto ByeBye;
|
||||||
|
}
|
||||||
|
Size += FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors)
|
||||||
|
+ pPartialResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
|
||||||
|
for (j = 0; j < pPartialResourceList->Count; j++)
|
||||||
|
{
|
||||||
|
if (pPartialResourceList->PartialDescriptors[j].Type == CmResourceTypeDeviceSpecific)
|
||||||
|
Size += pPartialResourceList->PartialDescriptors[j].u.DeviceSpecificData.DataSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceNode->ResourceList = ExAllocatePool(PagedPool, Size);
|
||||||
|
if (!DeviceNode->ResourceList)
|
||||||
|
{
|
||||||
|
Status = STATUS_NO_MEMORY;
|
||||||
|
goto ByeBye;
|
||||||
|
}
|
||||||
|
RtlCopyMemory(DeviceNode->ResourceList, DeviceNode->BootResources, Size);
|
||||||
|
|
||||||
|
*pRequiredSize = Size;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ok, here, we have to use the device requirement list */
|
||||||
IopDeviceNodeSetFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
|
IopDeviceNodeSetFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
|
||||||
|
|
||||||
/* FIXME: that's here that PnP arbiter should go */
|
|
||||||
/* Actually, simply use resource list #0 as assigned resource list */
|
|
||||||
ResourceList = &DeviceNode->ResourceRequirements->List[0];
|
ResourceList = &DeviceNode->ResourceRequirements->List[0];
|
||||||
if (ResourceList->Version != 1 || ResourceList->Revision != 1)
|
if (ResourceList->Version != 1 || ResourceList->Revision != 1)
|
||||||
{
|
{
|
||||||
|
@ -1260,19 +1294,12 @@ IopAssignDeviceResources(PDEVICE_NODE DeviceNode)
|
||||||
goto ByeBye;
|
goto ByeBye;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceNode->ResourceList = ExAllocatePool(PagedPool,
|
Size = sizeof(CM_RESOURCE_LIST) + ResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
|
||||||
sizeof(CM_RESOURCE_LIST) + ResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
|
*pRequiredSize = Size;
|
||||||
|
DeviceNode->ResourceList = ExAllocatePool(PagedPool, Size);
|
||||||
if (!DeviceNode->ResourceList)
|
if (!DeviceNode->ResourceList)
|
||||||
{
|
{
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
Status = STATUS_NO_MEMORY;
|
||||||
goto ByeBye;
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceNode->ResourceListTranslated = ExAllocatePool(PagedPool,
|
|
||||||
sizeof(CM_RESOURCE_LIST) + ResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
|
|
||||||
if (!DeviceNode->ResourceListTranslated)
|
|
||||||
{
|
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
goto ByeBye;
|
goto ByeBye;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1282,12 +1309,6 @@ IopAssignDeviceResources(PDEVICE_NODE DeviceNode)
|
||||||
DeviceNode->ResourceList->List[0].PartialResourceList.Version = 1;
|
DeviceNode->ResourceList->List[0].PartialResourceList.Version = 1;
|
||||||
DeviceNode->ResourceList->List[0].PartialResourceList.Revision = 1;
|
DeviceNode->ResourceList->List[0].PartialResourceList.Revision = 1;
|
||||||
|
|
||||||
DeviceNode->ResourceListTranslated->Count = 1;
|
|
||||||
DeviceNode->ResourceListTranslated->List[0].InterfaceType = DeviceNode->ResourceRequirements->InterfaceType;
|
|
||||||
DeviceNode->ResourceListTranslated->List[0].BusNumber = DeviceNode->ResourceRequirements->BusNumber;
|
|
||||||
DeviceNode->ResourceListTranslated->List[0].PartialResourceList.Version = 1;
|
|
||||||
DeviceNode->ResourceListTranslated->List[0].PartialResourceList.Revision = 1;
|
|
||||||
|
|
||||||
for (i = 0; i < ResourceList->Count; i++)
|
for (i = 0; i < ResourceList->Count; i++)
|
||||||
{
|
{
|
||||||
ResourceDescriptor = &ResourceList->Descriptors[i];
|
ResourceDescriptor = &ResourceList->Descriptors[i];
|
||||||
|
@ -1295,31 +1316,18 @@ IopAssignDeviceResources(PDEVICE_NODE DeviceNode)
|
||||||
if (ResourceDescriptor->Option == 0 || ResourceDescriptor->Option == IO_RESOURCE_PREFERRED)
|
if (ResourceDescriptor->Option == 0 || ResourceDescriptor->Option == IO_RESOURCE_PREFERRED)
|
||||||
{
|
{
|
||||||
DescriptorRaw = &DeviceNode->ResourceList->List[0].PartialResourceList.PartialDescriptors[NumberOfResources];
|
DescriptorRaw = &DeviceNode->ResourceList->List[0].PartialResourceList.PartialDescriptors[NumberOfResources];
|
||||||
DescriptorTranslated = &DeviceNode->ResourceListTranslated->List[0].PartialResourceList.PartialDescriptors[NumberOfResources];
|
|
||||||
NumberOfResources++;
|
NumberOfResources++;
|
||||||
|
|
||||||
/* Copy ResourceDescriptor to DescriptorRaw and DescriptorTranslated */
|
/* Copy ResourceDescriptor to DescriptorRaw and DescriptorTranslated */
|
||||||
DescriptorRaw->Type = DescriptorTranslated->Type = ResourceDescriptor->Type;
|
DescriptorRaw->Type = ResourceDescriptor->Type;
|
||||||
DescriptorRaw->ShareDisposition = DescriptorTranslated->ShareDisposition = ResourceDescriptor->ShareDisposition;
|
DescriptorRaw->ShareDisposition = ResourceDescriptor->ShareDisposition;
|
||||||
DescriptorRaw->Flags = DescriptorTranslated->Flags = ResourceDescriptor->Flags;
|
DescriptorRaw->Flags = ResourceDescriptor->Flags;
|
||||||
switch (ResourceDescriptor->Type)
|
switch (ResourceDescriptor->Type)
|
||||||
{
|
{
|
||||||
case CmResourceTypePort:
|
case CmResourceTypePort:
|
||||||
{
|
{
|
||||||
ULONG AddressSpace = 0; /* IO space */
|
|
||||||
DescriptorRaw->u.Port.Start = ResourceDescriptor->u.Port.MinimumAddress;
|
DescriptorRaw->u.Port.Start = ResourceDescriptor->u.Port.MinimumAddress;
|
||||||
DescriptorRaw->u.Port.Length = DescriptorTranslated->u.Port.Length
|
DescriptorRaw->u.Port.Length = ResourceDescriptor->u.Port.Length;
|
||||||
= ResourceDescriptor->u.Port.Length;
|
|
||||||
if (!HalTranslateBusAddress(
|
|
||||||
DeviceNode->ResourceRequirements->InterfaceType,
|
|
||||||
DeviceNode->ResourceRequirements->BusNumber,
|
|
||||||
DescriptorRaw->u.Port.Start,
|
|
||||||
&AddressSpace,
|
|
||||||
&DescriptorTranslated->u.Port.Start))
|
|
||||||
{
|
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
|
||||||
goto ByeBye;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CmResourceTypeInterrupt:
|
case CmResourceTypeInterrupt:
|
||||||
|
@ -1379,54 +1387,26 @@ IopAssignDeviceResources(PDEVICE_NODE DeviceNode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorTranslated->u.Interrupt.Level = 0;
|
|
||||||
DescriptorTranslated->u.Interrupt.Vector = HalGetInterruptVector(
|
|
||||||
DeviceNode->ResourceRequirements->InterfaceType,
|
|
||||||
DeviceNode->ResourceRequirements->BusNumber,
|
|
||||||
DescriptorRaw->u.Interrupt.Level,
|
|
||||||
DescriptorRaw->u.Interrupt.Vector,
|
|
||||||
(PKIRQL)&DescriptorTranslated->u.Interrupt.Level,
|
|
||||||
&DescriptorRaw->u.Interrupt.Affinity);
|
|
||||||
DescriptorTranslated->u.Interrupt.Affinity = DescriptorRaw->u.Interrupt.Affinity;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CmResourceTypeMemory:
|
case CmResourceTypeMemory:
|
||||||
{
|
{
|
||||||
ULONG AddressSpace = 1; /* Memory space */
|
|
||||||
DescriptorRaw->u.Memory.Start = ResourceDescriptor->u.Memory.MinimumAddress;
|
DescriptorRaw->u.Memory.Start = ResourceDescriptor->u.Memory.MinimumAddress;
|
||||||
DescriptorRaw->u.Memory.Length = DescriptorTranslated->u.Memory.Length
|
DescriptorRaw->u.Memory.Length = ResourceDescriptor->u.Memory.Length;
|
||||||
= ResourceDescriptor->u.Memory.Length;
|
|
||||||
if (!HalTranslateBusAddress(
|
|
||||||
DeviceNode->ResourceRequirements->InterfaceType,
|
|
||||||
DeviceNode->ResourceRequirements->BusNumber,
|
|
||||||
DescriptorRaw->u.Memory.Start,
|
|
||||||
&AddressSpace,
|
|
||||||
&DescriptorTranslated->u.Memory.Start))
|
|
||||||
{
|
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
|
||||||
goto ByeBye;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CmResourceTypeDma:
|
case CmResourceTypeDma:
|
||||||
{
|
{
|
||||||
DescriptorRaw->u.Dma.Channel = DescriptorTranslated->u.Dma.Channel
|
DescriptorRaw->u.Dma.Channel = ResourceDescriptor->u.Dma.MinimumChannel;
|
||||||
= ResourceDescriptor->u.Dma.MinimumChannel;
|
DescriptorRaw->u.Dma.Port = 0; /* FIXME */
|
||||||
DescriptorRaw->u.Dma.Port = DescriptorTranslated->u.Dma.Port
|
DescriptorRaw->u.Dma.Reserved1 = 0;
|
||||||
= 0; /* FIXME */
|
|
||||||
DescriptorRaw->u.Dma.Reserved1 = DescriptorTranslated->u.Dma.Reserved1
|
|
||||||
= 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CmResourceTypeBusNumber:
|
case CmResourceTypeBusNumber:
|
||||||
{
|
{
|
||||||
DescriptorRaw->u.BusNumber.Start = DescriptorTranslated->u.BusNumber.Start
|
DescriptorRaw->u.BusNumber.Start = ResourceDescriptor->u.BusNumber.MinBusNumber;
|
||||||
= ResourceDescriptor->u.BusNumber.MinBusNumber;
|
DescriptorRaw->u.BusNumber.Length = ResourceDescriptor->u.BusNumber.Length;
|
||||||
DescriptorRaw->u.BusNumber.Length = DescriptorTranslated->u.BusNumber.Length
|
DescriptorRaw->u.BusNumber.Reserved = ResourceDescriptor->u.BusNumber.Reserved;
|
||||||
= ResourceDescriptor->u.BusNumber.Length;
|
|
||||||
DescriptorRaw->u.BusNumber.Reserved = DescriptorTranslated->u.BusNumber.Reserved
|
|
||||||
= ResourceDescriptor->u.BusNumber.Reserved;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*CmResourceTypeDevicePrivate:
|
/*CmResourceTypeDevicePrivate:
|
||||||
|
@ -1452,10 +1432,7 @@ IopAssignDeviceResources(PDEVICE_NODE DeviceNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceNode->ResourceList->List[0].PartialResourceList.Count = NumberOfResources;
|
DeviceNode->ResourceList->List[0].PartialResourceList.Count = NumberOfResources;
|
||||||
DeviceNode->ResourceListTranslated->List[0].PartialResourceList.Count = NumberOfResources;
|
|
||||||
|
|
||||||
IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
|
|
||||||
IopDeviceNodeSetFlag(DeviceNode, DNF_RESOURCE_ASSIGNED);
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
ByeBye:
|
ByeBye:
|
||||||
|
@ -1464,13 +1441,111 @@ ByeBye:
|
||||||
ExFreePool(DeviceNode->ResourceList);
|
ExFreePool(DeviceNode->ResourceList);
|
||||||
DeviceNode->ResourceList = NULL;
|
DeviceNode->ResourceList = NULL;
|
||||||
}
|
}
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
IopTranslateDeviceResources(
|
||||||
|
IN PDEVICE_NODE DeviceNode,
|
||||||
|
IN ULONG RequiredSize)
|
||||||
|
{
|
||||||
|
PCM_PARTIAL_RESOURCE_LIST pPartialResourceList;
|
||||||
|
PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorRaw, DescriptorTranslated;
|
||||||
|
ULONG i, j;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
if (!DeviceNode->ResourceList)
|
||||||
|
{
|
||||||
|
DeviceNode->ResourceListTranslated = NULL;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* That's easy to translate a resource list. Just copy the
|
||||||
|
* untranslated one and change few fields in the copy
|
||||||
|
*/
|
||||||
|
DeviceNode->ResourceListTranslated = ExAllocatePool(PagedPool, RequiredSize);
|
||||||
|
if (!DeviceNode->ResourceListTranslated)
|
||||||
|
{
|
||||||
|
Status =STATUS_NO_MEMORY;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
RtlCopyMemory(DeviceNode->ResourceListTranslated, DeviceNode->ResourceList, RequiredSize);
|
||||||
|
|
||||||
|
for (i = 0; i < DeviceNode->ResourceList->Count; i++)
|
||||||
|
{
|
||||||
|
pPartialResourceList = &DeviceNode->ResourceList->List[i].PartialResourceList;
|
||||||
|
for (j = 0; j < pPartialResourceList->Count; j++)
|
||||||
|
{
|
||||||
|
DescriptorRaw = &pPartialResourceList->PartialDescriptors[j];
|
||||||
|
DescriptorTranslated = &DeviceNode->ResourceListTranslated->List[i].PartialResourceList.PartialDescriptors[j];
|
||||||
|
switch (DescriptorRaw->Type)
|
||||||
|
{
|
||||||
|
case CmResourceTypePort:
|
||||||
|
{
|
||||||
|
ULONG AddressSpace = 0; /* IO space */
|
||||||
|
if (!HalTranslateBusAddress(
|
||||||
|
DeviceNode->ResourceList->List[i].InterfaceType,
|
||||||
|
DeviceNode->ResourceList->List[i].BusNumber,
|
||||||
|
DescriptorRaw->u.Port.Start,
|
||||||
|
&AddressSpace,
|
||||||
|
&DescriptorTranslated->u.Port.Start))
|
||||||
|
{
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CmResourceTypeInterrupt:
|
||||||
|
{
|
||||||
|
DescriptorTranslated->u.Interrupt.Vector = HalGetInterruptVector(
|
||||||
|
DeviceNode->ResourceList->List[i].InterfaceType,
|
||||||
|
DeviceNode->ResourceList->List[i].BusNumber,
|
||||||
|
DescriptorRaw->u.Interrupt.Level,
|
||||||
|
DescriptorRaw->u.Interrupt.Vector,
|
||||||
|
(PKIRQL)&DescriptorTranslated->u.Interrupt.Level,
|
||||||
|
&DescriptorRaw->u.Interrupt.Affinity);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CmResourceTypeMemory:
|
||||||
|
{
|
||||||
|
ULONG AddressSpace = 1; /* Memory space */
|
||||||
|
if (!HalTranslateBusAddress(
|
||||||
|
DeviceNode->ResourceList->List[i].InterfaceType,
|
||||||
|
DeviceNode->ResourceList->List[i].BusNumber,
|
||||||
|
DescriptorRaw->u.Memory.Start,
|
||||||
|
&AddressSpace,
|
||||||
|
&DescriptorTranslated->u.Memory.Start))
|
||||||
|
{
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case CmResourceTypeDma:
|
||||||
|
case CmResourceTypeBusNumber:
|
||||||
|
case CmResourceTypeDeviceSpecific:
|
||||||
|
/* Nothing to do */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DPRINT1("Unknown resource descriptor type 0x%x\n", DescriptorRaw->Type);
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
/* Yes! Also delete ResourceList because ResourceList and
|
||||||
|
* ResourceListTranslated should be a pair! */
|
||||||
|
ExFreePool(DeviceNode->ResourceList);
|
||||||
|
DeviceNode->ResourceList = NULL;
|
||||||
if (DeviceNode->ResourceListTranslated)
|
if (DeviceNode->ResourceListTranslated)
|
||||||
{
|
{
|
||||||
ExFreePool(DeviceNode->ResourceListTranslated);
|
ExFreePool(DeviceNode->ResourceListTranslated);
|
||||||
DeviceNode->ResourceListTranslated = NULL;
|
DeviceNode->ResourceList = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2030,11 +2105,25 @@ IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
|
||||||
|
|
||||||
ZwClose(InstanceKey);
|
ZwClose(InstanceKey);
|
||||||
|
|
||||||
Status = IopAssignDeviceResources(DeviceNode);
|
IopDeviceNodeSetFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
|
||||||
if (!NT_SUCCESS(Status))
|
Status = IopAssignDeviceResources(DeviceNode, &RequiredLength);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("IopAssignDeviceResources() failed (Status %x)\n", Status);
|
Status = IopTranslateDeviceResources(DeviceNode, RequiredLength);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
IopDeviceNodeSetFlag(DeviceNode, DNF_RESOURCE_ASSIGNED);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("IopTranslateDeviceResources() failed (Status 0x08lx)\n", Status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT("IopAssignDeviceResources() failed (Status 0x08lx)\n", Status);
|
||||||
|
}
|
||||||
|
IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
|
||||||
|
|
||||||
DeviceNode->Flags |= DNF_PROCESSED;
|
DeviceNode->Flags |= DNF_PROCESSED;
|
||||||
|
|
||||||
|
@ -2596,7 +2685,9 @@ IopEnumerateDetectedDevices(
|
||||||
IN HANDLE hBaseKey,
|
IN HANDLE hBaseKey,
|
||||||
IN PUNICODE_STRING RelativePath,
|
IN PUNICODE_STRING RelativePath,
|
||||||
IN HANDLE hRootKey,
|
IN HANDLE hRootKey,
|
||||||
IN BOOLEAN EnumerateSubKeys)
|
IN BOOLEAN EnumerateSubKeys,
|
||||||
|
IN PCM_FULL_RESOURCE_DESCRIPTOR ParentBootResources,
|
||||||
|
IN ULONG ParentBootResourcesLength)
|
||||||
{
|
{
|
||||||
UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier");
|
UNICODE_STRING IdentifierU = RTL_CONSTANT_STRING(L"Identifier");
|
||||||
UNICODE_STRING DeviceDescU = RTL_CONSTANT_STRING(L"DeviceDesc");
|
UNICODE_STRING DeviceDescU = RTL_CONSTANT_STRING(L"DeviceDesc");
|
||||||
|
@ -2618,6 +2709,8 @@ IopEnumerateDetectedDevices(
|
||||||
ULONG ValueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 50 * sizeof(WCHAR);
|
ULONG ValueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 50 * sizeof(WCHAR);
|
||||||
UNICODE_STRING DeviceName, ValueName;
|
UNICODE_STRING DeviceName, ValueName;
|
||||||
ULONG RequiredSize;
|
ULONG RequiredSize;
|
||||||
|
PCM_FULL_RESOURCE_DESCRIPTOR BootResources = NULL;
|
||||||
|
ULONG BootResourcesLength;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
const UNICODE_STRING IdentifierPci = RTL_CONSTANT_STRING(L"PCI BIOS");
|
const UNICODE_STRING IdentifierPci = RTL_CONSTANT_STRING(L"PCI BIOS");
|
||||||
|
@ -2701,6 +2794,87 @@ IopEnumerateDetectedDevices(
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read boot resources, and add then to parent ones */
|
||||||
|
Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
|
||||||
|
if (Status == STATUS_BUFFER_OVERFLOW)
|
||||||
|
{
|
||||||
|
ExFreePool(pValueInformation);
|
||||||
|
ValueInfoLength = RequiredSize;
|
||||||
|
pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength);
|
||||||
|
if (!pValueInformation)
|
||||||
|
{
|
||||||
|
DPRINT("ExAllocatePool() failed\n");
|
||||||
|
ZwDeleteKey(hLevel2Key);
|
||||||
|
Status = STATUS_NO_MEMORY;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
|
||||||
|
}
|
||||||
|
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||||
|
{
|
||||||
|
BootResources = ParentBootResources;
|
||||||
|
BootResourcesLength = ParentBootResourcesLength;
|
||||||
|
}
|
||||||
|
else if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
|
||||||
|
goto nextdevice;
|
||||||
|
}
|
||||||
|
else if (pValueInformation->Type != REG_FULL_RESOURCE_DESCRIPTOR)
|
||||||
|
{
|
||||||
|
DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_FULL_RESOURCE_DESCRIPTOR);
|
||||||
|
goto nextdevice;
|
||||||
|
}
|
||||||
|
else if (((PCM_FULL_RESOURCE_DESCRIPTOR)pValueInformation->Data)->PartialResourceList.Count == 0)
|
||||||
|
{
|
||||||
|
BootResources = ParentBootResources;
|
||||||
|
BootResourcesLength = ParentBootResourcesLength;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static const ULONG Header = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList.PartialDescriptors);
|
||||||
|
|
||||||
|
/* Concatenate current resources and parent ones */
|
||||||
|
if (ParentBootResourcesLength == 0)
|
||||||
|
BootResourcesLength = pValueInformation->DataLength;
|
||||||
|
else
|
||||||
|
BootResourcesLength = ParentBootResourcesLength
|
||||||
|
+ pValueInformation->DataLength
|
||||||
|
- Header;
|
||||||
|
BootResources = ExAllocatePool(PagedPool, BootResourcesLength);
|
||||||
|
if (!BootResources)
|
||||||
|
{
|
||||||
|
DPRINT("ExAllocatePool() failed\n");
|
||||||
|
goto nextdevice;
|
||||||
|
}
|
||||||
|
if (ParentBootResourcesLength == 0)
|
||||||
|
{
|
||||||
|
RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength);
|
||||||
|
}
|
||||||
|
else if (ParentBootResources->PartialResourceList.PartialDescriptors[ParentBootResources->PartialResourceList.Count - 1].Type == CmResourceTypeDeviceSpecific)
|
||||||
|
{
|
||||||
|
RtlCopyMemory(BootResources, pValueInformation->Data, pValueInformation->DataLength);
|
||||||
|
RtlCopyMemory(
|
||||||
|
(PVOID)((ULONG_PTR)BootResources + pValueInformation->DataLength),
|
||||||
|
(PVOID)((ULONG_PTR)ParentBootResources + Header),
|
||||||
|
ParentBootResourcesLength - Header);
|
||||||
|
BootResources->PartialResourceList.Count += ParentBootResources->PartialResourceList.Count;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RtlCopyMemory(BootResources, pValueInformation->Data, Header);
|
||||||
|
RtlCopyMemory(
|
||||||
|
(PVOID)((ULONG_PTR)BootResources + Header),
|
||||||
|
(PVOID)((ULONG_PTR)ParentBootResources + Header),
|
||||||
|
ParentBootResourcesLength - Header);
|
||||||
|
RtlCopyMemory(
|
||||||
|
(PVOID)((ULONG_PTR)BootResources + ParentBootResourcesLength),
|
||||||
|
pValueInformation->Data + Header,
|
||||||
|
pValueInformation->DataLength - Header);
|
||||||
|
BootResources->PartialResourceList.Count += ParentBootResources->PartialResourceList.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (EnumerateSubKeys)
|
if (EnumerateSubKeys)
|
||||||
{
|
{
|
||||||
IndexSubKey = 0;
|
IndexSubKey = 0;
|
||||||
|
@ -2731,7 +2905,13 @@ IopEnumerateDetectedDevices(
|
||||||
DeviceName.Length = DeviceName.MaximumLength = pDeviceInformation->NameLength;
|
DeviceName.Length = DeviceName.MaximumLength = pDeviceInformation->NameLength;
|
||||||
DeviceName.Buffer = pDeviceInformation->Name;
|
DeviceName.Buffer = pDeviceInformation->Name;
|
||||||
|
|
||||||
Status = IopEnumerateDetectedDevices(hDeviceKey, &DeviceName, hRootKey, TRUE);
|
Status = IopEnumerateDetectedDevices(
|
||||||
|
hDeviceKey,
|
||||||
|
&DeviceName,
|
||||||
|
hRootKey,
|
||||||
|
TRUE,
|
||||||
|
BootResources,
|
||||||
|
BootResourcesLength);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
@ -2754,31 +2934,27 @@ IopEnumerateDetectedDevices(
|
||||||
}
|
}
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
|
if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
|
||||||
goto nextdevice;
|
{
|
||||||
|
DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
|
||||||
|
goto nextdevice;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (pValueInformation->Type != REG_SZ)
|
else if (pValueInformation->Type != REG_SZ)
|
||||||
{
|
{
|
||||||
DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ);
|
DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ);
|
||||||
goto nextdevice;
|
goto nextdevice;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* Assign hardware id to this device */
|
|
||||||
ValueName.Length = ValueName.MaximumLength = pValueInformation->DataLength;
|
|
||||||
ValueName.Buffer = (PWCHAR)pValueInformation->Data;
|
|
||||||
if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL)
|
|
||||||
ValueName.Length -= sizeof(WCHAR);
|
|
||||||
if (RtlCompareUnicodeString(&ValueName, &IdentifierPci, FALSE) == 0)
|
|
||||||
{
|
{
|
||||||
pHardwareId = &HardwareIdPci;
|
/* Assign hardware id to this device */
|
||||||
DeviceIndex = DeviceIndexPci++;
|
ValueName.Length = ValueName.MaximumLength = pValueInformation->DataLength;
|
||||||
|
ValueName.Buffer = (PWCHAR)pValueInformation->Data;
|
||||||
|
if (ValueName.Length >= sizeof(WCHAR) && ValueName.Buffer[ValueName.Length / sizeof(WCHAR) - 1] == UNICODE_NULL)
|
||||||
|
ValueName.Length -= sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
/*else if (RtlCompareUnicodeString(&ValueName, &IdentifierAcpi, FALSE) == 0)
|
|
||||||
{
|
if (RtlCompareUnicodeString(RelativePath, &IdentifierSerial, FALSE) == 0)
|
||||||
pHardwareId = &HardwareIdAcpi;
|
|
||||||
DeviceIndex = DeviceIndexAcpi++;
|
|
||||||
}*/
|
|
||||||
else if (RtlCompareUnicodeString(RelativePath, &IdentifierSerial, FALSE) == 0)
|
|
||||||
{
|
{
|
||||||
pHardwareId = &HardwareIdSerial;
|
pHardwareId = &HardwareIdSerial;
|
||||||
DeviceIndex = DeviceIndexSerial++;
|
DeviceIndex = DeviceIndexSerial++;
|
||||||
|
@ -2793,10 +2969,30 @@ IopEnumerateDetectedDevices(
|
||||||
pHardwareId = &HardwareIdMouse;
|
pHardwareId = &HardwareIdMouse;
|
||||||
DeviceIndex = DeviceIndexMouse++;
|
DeviceIndex = DeviceIndexMouse++;
|
||||||
}
|
}
|
||||||
|
else if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Try to also match the device identifier */
|
||||||
|
if (RtlCompareUnicodeString(&ValueName, &IdentifierPci, FALSE) == 0)
|
||||||
|
{
|
||||||
|
pHardwareId = &HardwareIdPci;
|
||||||
|
DeviceIndex = DeviceIndexPci++;
|
||||||
|
}
|
||||||
|
/*else if (RtlCompareUnicodeString(&ValueName, &IdentifierAcpi, FALSE) == 0)
|
||||||
|
{
|
||||||
|
pHardwareId = &HardwareIdAcpi;
|
||||||
|
DeviceIndex = DeviceIndexAcpi++;
|
||||||
|
}*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Unknown device */
|
||||||
|
DPRINT("Unknown device '%wZ'\n", &ValueName);
|
||||||
|
goto nextdevice;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Unknown device */
|
/* Unknown key path */
|
||||||
DPRINT("Unknown device %wZ in %wZ\n", &ValueName, RelativePath);
|
DPRINT("Unknown key path %wZ\n", RelativePath);
|
||||||
goto nextdevice;
|
goto nextdevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2847,61 +3043,37 @@ IopEnumerateDetectedDevices(
|
||||||
ZwDeleteKey(hLevel2Key);
|
ZwDeleteKey(hLevel2Key);
|
||||||
goto nextdevice;
|
goto nextdevice;
|
||||||
}
|
}
|
||||||
/* Copy 'Configuration Data' to 'LogConf\BootConfig' */
|
if (BootResourcesLength > 0)
|
||||||
Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
|
|
||||||
if (Status == STATUS_BUFFER_OVERFLOW)
|
|
||||||
{
|
{
|
||||||
ExFreePool(pValueInformation);
|
/* Save boot resources to 'LogConf\BootConfig' */
|
||||||
ValueInfoLength = RequiredSize;
|
InitializeObjectAttributes(&ObjectAttributes, &LogConfU, OBJ_KERNEL_HANDLE, hLevel2Key, NULL);
|
||||||
pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength);
|
Status = ZwCreateKey(
|
||||||
if (!pValueInformation)
|
&hLogConf,
|
||||||
|
KEY_SET_VALUE,
|
||||||
|
&ObjectAttributes,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
REG_OPTION_VOLATILE,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("ExAllocatePool() failed\n");
|
DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
|
||||||
ZwDeleteKey(hLevel2Key);
|
ZwDeleteKey(hLevel2Key);
|
||||||
Status = STATUS_NO_MEMORY;
|
goto nextdevice;
|
||||||
goto cleanup;
|
}
|
||||||
|
Status = ZwSetValueKey(hLogConf, &BootConfigU, 0, REG_FULL_RESOURCE_DESCRIPTOR, BootResources, BootResourcesLength);
|
||||||
|
ZwClose(hLogConf);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
|
||||||
|
ZwDeleteKey(hLevel2Key);
|
||||||
|
goto nextdevice;
|
||||||
}
|
}
|
||||||
Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
|
|
||||||
}
|
|
||||||
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
|
||||||
goto nextdevice;
|
|
||||||
else if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
|
|
||||||
ZwDeleteKey(hLevel2Key);
|
|
||||||
goto nextdevice;
|
|
||||||
}
|
|
||||||
else if (pValueInformation->Type != REG_FULL_RESOURCE_DESCRIPTOR)
|
|
||||||
{
|
|
||||||
DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_FULL_RESOURCE_DESCRIPTOR);
|
|
||||||
ZwDeleteKey(hLevel2Key);
|
|
||||||
goto nextdevice;
|
|
||||||
}
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes, &LogConfU, OBJ_KERNEL_HANDLE, hLevel2Key, NULL);
|
|
||||||
Status = ZwCreateKey(
|
|
||||||
&hLogConf,
|
|
||||||
KEY_SET_VALUE,
|
|
||||||
&ObjectAttributes,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
REG_OPTION_VOLATILE,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
|
|
||||||
ZwDeleteKey(hLevel2Key);
|
|
||||||
goto nextdevice;
|
|
||||||
}
|
|
||||||
Status = ZwSetValueKey(hLogConf, &BootConfigU, 0, pValueInformation->Type, pValueInformation->Data, pValueInformation->DataLength);
|
|
||||||
ZwClose(hLogConf);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
|
|
||||||
ZwDeleteKey(hLevel2Key);
|
|
||||||
goto nextdevice;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nextdevice:
|
nextdevice:
|
||||||
|
if (BootResources && BootResources != ParentBootResources)
|
||||||
|
ExFreePool(BootResources);
|
||||||
if (hLevel2Key)
|
if (hLevel2Key)
|
||||||
{
|
{
|
||||||
ZwClose(hLevel2Key);
|
ZwClose(hLevel2Key);
|
||||||
|
@ -3119,7 +3291,9 @@ IopUpdateRootKey(VOID)
|
||||||
NULL,
|
NULL,
|
||||||
&MultiKeyPathU,
|
&MultiKeyPathU,
|
||||||
hRoot,
|
hRoot,
|
||||||
TRUE);
|
TRUE,
|
||||||
|
NULL,
|
||||||
|
0);
|
||||||
ZwClose(hRoot);
|
ZwClose(hRoot);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue