#if defined (ALLOC_PRAGMA)
#pragma alloc_text(INIT, PnpInit)
#pragma alloc_text(INIT, PnpInit2)
-#pragma alloc_text(INIT, IopUpdateRootKey)
-#pragma alloc_text(INIT, IopEnumerateDetectedDevices)
-#pragma alloc_text(INIT, IopIsAcpiComputer)
#endif
typedef struct _INVALIDATE_DEVICE_RELATION_DATA
NTSTATUS Status;
} INVALIDATE_DEVICE_RELATION_DATA, *PINVALIDATE_DEVICE_RELATION_DATA;
-static VOID CALLBACK
+static VOID NTAPI
IopInvalidateDeviceRelations(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID InvalidateContext);
+VOID
+NTAPI
+IoSynchronousInvalidateDeviceRelations(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN DEVICE_RELATION_TYPE Type);
+
+
/* FUNCTIONS *****************************************************************/
PDEVICE_NODE
Stack.Parameters.StartDevice.AllocatedResources = DeviceNode->ResourceList;
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(
Fdo,
&IoStatusBlock,
if (IopDeviceNodeHasFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY))
{
DPRINT("Device needs enumeration, invalidating bus relations\n");
- IoInvalidateDeviceRelations(DeviceNode->PhysicalDeviceObject, BusRelations);
+ /* Invalidate device relations synchronously
+ (otherwise there will be dirty read of DeviceNode) */
+ IoSynchronousInvalidateDeviceRelations(DeviceNode->PhysicalDeviceObject, BusRelations);
IopDeviceNodeClearFlag(DeviceNode, DNF_NEED_ENUMERATION_ONLY);
}
}
return STATUS_INSUFFICIENT_RESOURCES;
KeyName.Length = 0;
- KeyName.MaximumLength = KeyNameLength;
+ KeyName.MaximumLength = (USHORT)KeyNameLength;
KeyName.Buffer = KeyNameBuffer;
/*
ExFreePool(KeyNameBuffer);
return Status;
}
- KeyName.Length += DriverKeyLength - sizeof(UNICODE_NULL);
+ KeyName.Length += (USHORT)DriverKeyLength - sizeof(UNICODE_NULL);
}
else
{
sizeof(GUID));
/* The new entry is the index */
- FoundIndex = IopBusTypeGuidList->GuidCount;
+ FoundIndex = (USHORT)IopBusTypeGuidList->GuidCount;
IopBusTypeGuidList->GuidCount++;
Quickie:
Irp->IoStatus.Information = 0;
IrpSp = IoGetNextIrpStackLocation(Irp);
- IrpSp->MinorFunction = MinorFunction;
+ IrpSp->MinorFunction = (UCHAR)MinorFunction;
if (Stack)
{
- RtlMoveMemory(&IrpSp->Parameters,
+ RtlCopyMemory(&IrpSp->Parameters,
&Stack->Parameters,
sizeof(Stack->Parameters));
}
}
-NTSTATUS
-IopAssignDeviceResources(PDEVICE_NODE DeviceNode)
+static NTSTATUS
+IopAssignDeviceResources(
+ IN PDEVICE_NODE DeviceNode,
+ OUT ULONG *pRequiredSize)
{
PIO_RESOURCE_LIST ResourceList;
PIO_RESOURCE_DESCRIPTOR ResourceDescriptor;
- PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorRaw, DescriptorTranslated;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorRaw;
+ PCM_PARTIAL_RESOURCE_LIST pPartialResourceList;
ULONG NumberOfResources = 0;
- ULONG i;
+ ULONG Size;
+ ULONG i, j;
NTSTATUS Status;
- /* Fill DeviceNode->ResourceList and DeviceNode->ResourceListTranslated;
- * by using DeviceNode->ResourceRequirements */
+ if (!DeviceNode->BootResources && !DeviceNode->ResourceRequirements)
+ {
+ /* No resource needed for this device */
+ DeviceNode->ResourceList = NULL;
+ 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->ResourceRequirements
- || DeviceNode->ResourceRequirements->AlternativeLists == 0)
+ if (DeviceNode->BootResources)
{
- DeviceNode->ResourceList = DeviceNode->ResourceListTranslated = NULL;
+ /* 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);
- /* FIXME: that's here that PnP arbiter should go */
- /* Actually, simply use resource list #0 as assigned resource list */
ResourceList = &DeviceNode->ResourceRequirements->List[0];
if (ResourceList->Version != 1 || ResourceList->Revision != 1)
{
goto ByeBye;
}
- DeviceNode->ResourceList = ExAllocatePool(PagedPool,
- sizeof(CM_RESOURCE_LIST) + ResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
+ Size = sizeof(CM_RESOURCE_LIST) + ResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+ *pRequiredSize = Size;
+ DeviceNode->ResourceList = ExAllocatePool(PagedPool, Size);
if (!DeviceNode->ResourceList)
{
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto ByeBye;
- }
-
- DeviceNode->ResourceListTranslated = ExAllocatePool(PagedPool,
- sizeof(CM_RESOURCE_LIST) + ResourceList->Count * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
- if (!DeviceNode->ResourceListTranslated)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
+ Status = STATUS_NO_MEMORY;
goto ByeBye;
}
DeviceNode->ResourceList->List[0].PartialResourceList.Version = 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++)
{
ResourceDescriptor = &ResourceList->Descriptors[i];
if (ResourceDescriptor->Option == 0 || ResourceDescriptor->Option == IO_RESOURCE_PREFERRED)
{
DescriptorRaw = &DeviceNode->ResourceList->List[0].PartialResourceList.PartialDescriptors[NumberOfResources];
- DescriptorTranslated = &DeviceNode->ResourceListTranslated->List[0].PartialResourceList.PartialDescriptors[NumberOfResources];
NumberOfResources++;
/* Copy ResourceDescriptor to DescriptorRaw and DescriptorTranslated */
- DescriptorRaw->Type = DescriptorTranslated->Type = ResourceDescriptor->Type;
- DescriptorRaw->ShareDisposition = DescriptorTranslated->ShareDisposition = ResourceDescriptor->ShareDisposition;
- DescriptorRaw->Flags = DescriptorTranslated->Flags = ResourceDescriptor->Flags;
+ DescriptorRaw->Type = ResourceDescriptor->Type;
+ DescriptorRaw->ShareDisposition = ResourceDescriptor->ShareDisposition;
+ DescriptorRaw->Flags = ResourceDescriptor->Flags;
switch (ResourceDescriptor->Type)
{
case CmResourceTypePort:
{
- ULONG AddressSpace = 0; /* IO space */
DescriptorRaw->u.Port.Start = ResourceDescriptor->u.Port.MinimumAddress;
- DescriptorRaw->u.Port.Length = DescriptorTranslated->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;
- }
+ DescriptorRaw->u.Port.Length = ResourceDescriptor->u.Port.Length;
break;
}
case CmResourceTypeInterrupt:
}
}
}
-
- 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;
}
case CmResourceTypeMemory:
{
- ULONG AddressSpace = 1; /* Memory space */
DescriptorRaw->u.Memory.Start = ResourceDescriptor->u.Memory.MinimumAddress;
- DescriptorRaw->u.Memory.Length = DescriptorTranslated->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;
- }
+ DescriptorRaw->u.Memory.Length = ResourceDescriptor->u.Memory.Length;
break;
}
case CmResourceTypeDma:
{
- DescriptorRaw->u.Dma.Channel = DescriptorTranslated->u.Dma.Channel
- = ResourceDescriptor->u.Dma.MinimumChannel;
- DescriptorRaw->u.Dma.Port = DescriptorTranslated->u.Dma.Port
- = 0; /* FIXME */
- DescriptorRaw->u.Dma.Reserved1 = DescriptorTranslated->u.Dma.Reserved1
- = 0;
+ DescriptorRaw->u.Dma.Channel = ResourceDescriptor->u.Dma.MinimumChannel;
+ DescriptorRaw->u.Dma.Port = 0; /* FIXME */
+ DescriptorRaw->u.Dma.Reserved1 = 0;
break;
}
case CmResourceTypeBusNumber:
{
- DescriptorRaw->u.BusNumber.Start = DescriptorTranslated->u.BusNumber.Start
- = ResourceDescriptor->u.BusNumber.MinBusNumber;
- DescriptorRaw->u.BusNumber.Length = DescriptorTranslated->u.BusNumber.Length
- = ResourceDescriptor->u.BusNumber.Length;
- DescriptorRaw->u.BusNumber.Reserved = DescriptorTranslated->u.BusNumber.Reserved
- = ResourceDescriptor->u.BusNumber.Reserved;
+ DescriptorRaw->u.BusNumber.Start = ResourceDescriptor->u.BusNumber.MinBusNumber;
+ DescriptorRaw->u.BusNumber.Length = ResourceDescriptor->u.BusNumber.Length;
+ DescriptorRaw->u.BusNumber.Reserved = ResourceDescriptor->u.BusNumber.Reserved;
break;
}
/*CmResourceTypeDevicePrivate:
}
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;
ByeBye:
ExFreePool(DeviceNode->ResourceList);
DeviceNode->ResourceList = NULL;
}
- if (DeviceNode->ResourceListTranslated)
+ 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)
{
- ExFreePool(DeviceNode->ResourceListTranslated);
DeviceNode->ResourceListTranslated = NULL;
+ return STATUS_SUCCESS;
}
- IopDeviceNodeClearFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
+ /* 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)
+ {
+ ExFreePool(DeviceNode->ResourceListTranslated);
+ DeviceNode->ResourceList = NULL;
+ }
return Status;
}
Status = STATUS_UNSUCCESSFUL;
else
{
- KeyValue.Length = KeyValue.MaximumLength = ParentIdPrefixInformation->DataLength;
+ KeyValue.Length = KeyValue.MaximumLength = (USHORT)ParentIdPrefixInformation->DataLength;
KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
}
goto cleanup;
}
if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
{
- KeyValue.Length = KeyValue.MaximumLength = ParentIdPrefixInformation->DataLength;
+ KeyValue.Length = KeyValue.MaximumLength = (USHORT)ParentIdPrefixInformation->DataLength;
KeyValue.Buffer = (PWSTR)ParentIdPrefixInformation->Data;
goto cleanup;
}
ZwClose(InstanceKey);
- Status = IopAssignDeviceResources(DeviceNode);
- if (!NT_SUCCESS(Status))
+ IopDeviceNodeSetFlag(DeviceNode, DNF_ASSIGNING_RESOURCES);
+ 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;
PLDR_DATA_TABLE_ENTRY ModuleObject;
PDRIVER_OBJECT DriverObject;
+ /* FIXME: Remove this once the bug is fixed */
+ if (DeviceNode->ServiceName.Buffer == NULL)
+ DPRINT1("Weird DeviceNode %p having ServiceName->Buffer==NULL. Probable stack corruption or memory overwrite.\n", DeviceNode);
+
Status = IopLoadServiceModule(&DeviceNode->ServiceName, &ModuleObject);
if (NT_SUCCESS(Status) || Status == STATUS_IMAGE_ALREADY_LOADED)
{
* The call can be make synchronous by defining the Event field
* of the INVALIDATE_DEVICE_RELATION_DATA structure
*/
-static VOID CALLBACK
+static VOID NTAPI
IopInvalidateDeviceRelations(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID InvalidateContext) /* PINVALIDATE_DEVICE_RELATION_DATA */
NTSTATUS Status;
ULONG i;
- DPRINT("DeviceObject 0x%p, Type %d\n", DeviceObject, Type);
+ DPRINT("DeviceObject 0x%p\n", DeviceObject);
DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n");
ExFreePool(Data);
}
-VOID INIT_FUNCTION
-PnpInit(VOID)
-{
- PDEVICE_OBJECT Pdo;
- NTSTATUS Status;
-
- DPRINT("PnpInit()\n");
-
- KeInitializeSpinLock(&IopDeviceTreeLock);
-
- /* Initialize the Bus Type GUID List */
- IopBusTypeGuidList = ExAllocatePool(PagedPool, sizeof(IO_BUS_TYPE_GUID_LIST));
- RtlZeroMemory(IopBusTypeGuidList, sizeof(IO_BUS_TYPE_GUID_LIST));
- ExInitializeFastMutex(&IopBusTypeGuidList->Lock);
-
- /* Initialize PnP-Event notification support */
- Status = IopInitPlugPlayEvents();
- if (!NT_SUCCESS(Status))
- {
- CPRINT("IopInitPlugPlayEvents() failed\n");
- KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
- }
-
- /*
- * Create root device node
- */
-
- Status = IopCreateDriverObject(&IopRootDriverObject, NULL, 0, FALSE, NULL, 0);
- if (!NT_SUCCESS(Status))
- {
- CPRINT("IoCreateDriverObject() failed\n");
- KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
- }
-
- Status = IoCreateDevice(IopRootDriverObject, 0, NULL, FILE_DEVICE_CONTROLLER,
- 0, FALSE, &Pdo);
- if (!NT_SUCCESS(Status))
- {
- CPRINT("IoCreateDevice() failed\n");
- KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
- }
-
- Status = IopCreateDeviceNode(NULL, Pdo, &IopRootDeviceNode);
- if (!NT_SUCCESS(Status))
- {
- CPRINT("Insufficient resources\n");
- KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
- }
-
- if (!RtlCreateUnicodeString(&IopRootDeviceNode->InstancePath,
- L"HTREE\\ROOT\\0"))
- {
- CPRINT("Failed to create the instance path!\n");
- KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, STATUS_NO_MEMORY, 0, 0, 0);
- }
-
- /* Report the device to the user-mode pnp manager */
- IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL,
- &IopRootDeviceNode->InstancePath);
-
- IopRootDeviceNode->PhysicalDeviceObject->Flags |= DO_BUS_ENUMERATED_DEVICE;
- PnpRootDriverEntry(IopRootDriverObject, NULL);
- IopRootDriverObject->DriverExtension->AddDevice(
- IopRootDriverObject,
- IopRootDeviceNode->PhysicalDeviceObject);
-}
-
static NTSTATUS INIT_FUNCTION
IopEnumerateDetectedDevices(
IN HANDLE hBaseKey,
IN PUNICODE_STRING RelativePath,
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 DeviceDescU = RTL_CONSTANT_STRING(L"DeviceDesc");
ULONG ValueInfoLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 50 * sizeof(WCHAR);
UNICODE_STRING DeviceName, ValueName;
ULONG RequiredSize;
+ PCM_FULL_RESOURCE_DESCRIPTOR BootResources = NULL;
+ ULONG BootResourcesLength;
NTSTATUS Status;
const UNICODE_STRING IdentifierPci = RTL_CONSTANT_STRING(L"PCI BIOS");
const UNICODE_STRING IdentifierSerial = RTL_CONSTANT_STRING(L"SerialController");
UNICODE_STRING HardwareIdSerial = RTL_CONSTANT_STRING(L"*PNP0501\0");
static ULONG DeviceIndexSerial = 0;
- const UNICODE_STRING IdentifierKeyboard = RTL_CONSTANT_STRING(L"KeyboardPeripheral");
+ const UNICODE_STRING IdentifierKeyboard = RTL_CONSTANT_STRING(L"KeyboardController");
UNICODE_STRING HardwareIdKeyboard = RTL_CONSTANT_STRING(L"*PNP0303\0");
static ULONG DeviceIndexKeyboard = 0;
- const UNICODE_STRING IdentifierMouse = RTL_CONSTANT_STRING(L"PointerPeripheral");
+ const UNICODE_STRING IdentifierMouse = RTL_CONSTANT_STRING(L"PointerController");
UNICODE_STRING HardwareIdMouse = RTL_CONSTANT_STRING(L"*PNP0F13\0");
static ULONG DeviceIndexMouse = 0;
PUNICODE_STRING pHardwareId;
IndexDevice++;
/* Open device key */
- DeviceName.Length = DeviceName.MaximumLength = pDeviceInformation->NameLength;
+ DeviceName.Length = DeviceName.MaximumLength = (USHORT)pDeviceInformation->NameLength;
DeviceName.Buffer = pDeviceInformation->Name;
InitializeObjectAttributes(&ObjectAttributes, &DeviceName, OBJ_KERNEL_HANDLE, hDevicesKey, NULL);
Status = ZwOpenKey(
&hDeviceKey,
- KEY_QUERY_VALUE + EnumerateSubKeys ? KEY_ENUMERATE_SUB_KEYS : 0,
+ KEY_QUERY_VALUE + (EnumerateSubKeys ? KEY_ENUMERATE_SUB_KEYS : 0),
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
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)
{
IndexSubKey = 0;
goto cleanup;
}
IndexSubKey++;
- DeviceName.Length = DeviceName.MaximumLength = pDeviceInformation->NameLength;
+ DeviceName.Length = DeviceName.MaximumLength = (USHORT)pDeviceInformation->NameLength;
DeviceName.Buffer = pDeviceInformation->Name;
- Status = IopEnumerateDetectedDevices(hDeviceKey, &DeviceName, hRootKey, TRUE);
+ Status = IopEnumerateDetectedDevices(
+ hDeviceKey,
+ &DeviceName,
+ hRootKey,
+ TRUE,
+ BootResources,
+ BootResourcesLength);
if (!NT_SUCCESS(Status))
goto cleanup;
}
}
if (!NT_SUCCESS(Status))
{
- DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
- goto nextdevice;
+ if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
+ {
+ DPRINT("ZwQueryValueKey() failed with status 0x%08lx\n", Status);
+ goto nextdevice;
+ }
}
else if (pValueInformation->Type != REG_SZ)
{
DPRINT("Wrong registry type: got 0x%lx, expected 0x%lx\n", pValueInformation->Type, REG_SZ);
goto nextdevice;
}
-
- /* 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)
+ else
{
- pHardwareId = &HardwareIdPci;
- DeviceIndex = DeviceIndexPci++;
+ /* Assign hardware id to this device */
+ ValueName.Length = ValueName.MaximumLength = (USHORT)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)
- {
- pHardwareId = &HardwareIdAcpi;
- DeviceIndex = DeviceIndexAcpi++;
- }*/
- else if (RtlCompareUnicodeString(RelativePath, &IdentifierSerial, FALSE) == 0)
+
+ if (RtlCompareUnicodeString(RelativePath, &IdentifierSerial, FALSE) == 0)
{
pHardwareId = &HardwareIdSerial;
DeviceIndex = DeviceIndexSerial++;
pHardwareId = &HardwareIdMouse;
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
{
- /* Unknown device */
- DPRINT("Unknown device %wZ in %wZ\n", &ValueName, RelativePath);
+ /* Unknown key path */
+ DPRINT("Unknown key path %wZ\n", RelativePath);
goto nextdevice;
}
&ObjectAttributes,
0,
NULL,
- REG_OPTION_VOLATILE,
+ REG_OPTION_NON_VOLATILE,
NULL);
if (!NT_SUCCESS(Status))
{
&ObjectAttributes,
0,
NULL,
- REG_OPTION_VOLATILE,
+ REG_OPTION_NON_VOLATILE,
NULL);
ZwClose(hLevel1Key);
if (!NT_SUCCESS(Status))
ZwDeleteKey(hLevel2Key);
goto nextdevice;
}
- /* Copy 'Configuration Data' to 'LogConf\BootConfig' */
- Status = ZwQueryValueKey(hDeviceKey, &ConfigurationDataU, KeyValuePartialInformation, pValueInformation, ValueInfoLength, &RequiredSize);
- if (Status == STATUS_BUFFER_OVERFLOW)
+ if (BootResourcesLength > 0)
{
- ExFreePool(pValueInformation);
- ValueInfoLength = RequiredSize;
- pValueInformation = ExAllocatePool(PagedPool, ValueInfoLength);
- if (!pValueInformation)
+ /* Save boot resources to 'LogConf\BootConfig' */
+ 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("ExAllocatePool() failed\n");
+ DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
ZwDeleteKey(hLevel2Key);
- Status = STATUS_NO_MEMORY;
- goto cleanup;
+ goto nextdevice;
+ }
+ 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:
+ if (BootResources && BootResources != ParentBootResources)
+ ExFreePool(BootResources);
if (hLevel2Key)
{
ZwClose(hLevel2Key);
NULL,
&MultiKeyPathU,
hRoot,
- TRUE);
+ TRUE,
+ NULL,
+ 0);
ZwClose(hRoot);
return Status;
}
}
VOID INIT_FUNCTION
-PnpInit2(VOID)
+PnpInit(VOID)
{
- NTSTATUS Status;
+ PDEVICE_OBJECT Pdo;
+ NTSTATUS Status;
- /* Move information about devices detected by Freeloader to SYSTEM\CurrentControlSet\Root\ */
- Status = IopUpdateRootKey();
- if (!NT_SUCCESS(Status))
- {
- CPRINT("IopUpdateRootKey() failed\n");
- KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
- }
+ DPRINT("PnpInit()\n");
+
+ KeInitializeSpinLock(&IopDeviceTreeLock);
+
+ /* Initialize the Bus Type GUID List */
+ IopBusTypeGuidList = ExAllocatePool(PagedPool, sizeof(IO_BUS_TYPE_GUID_LIST));
+ RtlZeroMemory(IopBusTypeGuidList, sizeof(IO_BUS_TYPE_GUID_LIST));
+ ExInitializeFastMutex(&IopBusTypeGuidList->Lock);
+
+ /* Initialize PnP-Event notification support */
+ Status = IopInitPlugPlayEvents();
+ if (!NT_SUCCESS(Status))
+ {
+ CPRINT("IopInitPlugPlayEvents() failed\n");
+ KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
+ }
+
+ /*
+ * Create root device node
+ */
+
+ Status = IopCreateDriverObject(&IopRootDriverObject, NULL, 0, FALSE, NULL, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ CPRINT("IoCreateDriverObject() failed\n");
+ KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
+ }
+
+ Status = IoCreateDevice(IopRootDriverObject, 0, NULL, FILE_DEVICE_CONTROLLER,
+ 0, FALSE, &Pdo);
+ if (!NT_SUCCESS(Status))
+ {
+ CPRINT("IoCreateDevice() failed\n");
+ KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
+ }
+
+ Status = IopCreateDeviceNode(NULL, Pdo, &IopRootDeviceNode);
+ if (!NT_SUCCESS(Status))
+ {
+ CPRINT("Insufficient resources\n");
+ KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
+ }
+
+ if (!RtlCreateUnicodeString(&IopRootDeviceNode->InstancePath,
+ L"HTREE\\ROOT\\0"))
+ {
+ CPRINT("Failed to create the instance path!\n");
+ KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, STATUS_NO_MEMORY, 0, 0, 0);
+ }
+
+ /* Report the device to the user-mode pnp manager */
+ IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL,
+ &IopRootDeviceNode->InstancePath);
+
+ IopRootDeviceNode->PhysicalDeviceObject->Flags |= DO_BUS_ENUMERATED_DEVICE;
+ PnpRootDriverEntry(IopRootDriverObject, NULL);
+ IopRootDriverObject->DriverExtension->AddDevice(
+ IopRootDriverObject,
+ IopRootDeviceNode->PhysicalDeviceObject);
+
+ /* Move information about devices detected by Freeloader to SYSTEM\CurrentControlSet\Root\ */
+ Status = IopUpdateRootKey();
+ if (!NT_SUCCESS(Status))
+ {
+ CPRINT("IopUpdateRootKey() failed\n");
+ KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
+ }
}
+
/* EOF */