X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Fntoskrnl%2Fio%2Fpnpmgr%2Fpnproot.c;h=7a62ed23ca89acadbe6f8a233bfb2e4a69bbd2f2;hp=a5fa2a04f0c49e210c193d067247bf7343465d6d;hb=f3683186aa6f551568e54e3bc6f70089ca9b0a5b;hpb=b1214477449232d8359d1d14a3b0a801a8405e7d diff --git a/reactos/ntoskrnl/io/pnpmgr/pnproot.c b/reactos/ntoskrnl/io/pnpmgr/pnproot.c index a5fa2a04f0c..7a62ed23ca8 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnproot.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnproot.c @@ -33,7 +33,6 @@ typedef struct _PNPROOT_DEVICE UNICODE_STRING DeviceDescription; // Resource requirement list PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirementsList; - ULONG ResourceRequirementsListSize; // Associated resource list PCM_RESOURCE_LIST ResourceList; ULONG ResourceListSize; @@ -140,29 +139,19 @@ PnpRootCreateDevice( WCHAR InstancePath[5]; PPNPROOT_DEVICE Device = NULL; NTSTATUS Status; - ULONG i; UNICODE_STRING PathSep = RTL_CONSTANT_STRING(L"\\"); + ULONG NextInstance; + UNICODE_STRING EnumKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\" REGSTR_PATH_SYSTEMENUM); + HANDLE EnumHandle, DeviceKeyHandle = INVALID_HANDLE_VALUE; + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + OBJECT_ATTRIBUTES ObjectAttributes; DeviceExtension = PnpRootDeviceObject->DeviceExtension; KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock); DPRINT("Creating a PnP root device for service '%wZ'\n", ServiceName); - /* Search for a free instance ID */ _snwprintf(DevicePath, sizeof(DevicePath) / sizeof(WCHAR), L"%s\\%wZ", REGSTR_KEY_ROOTENUM, ServiceName); - for (i = 0; i < 9999; i++) - { - _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", i); - Status = LocateChildDevice(DeviceExtension, DevicePath, InstancePath, &Device); - if (Status == STATUS_NO_SUCH_DEVICE) - break; - } - if (i == 9999) - { - DPRINT1("Too much legacy devices reported for service '%wZ'\n", ServiceName); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } /* Initialize a PNPROOT_DEVICE structure */ Device = ExAllocatePoolWithTag(PagedPool, sizeof(PNPROOT_DEVICE), TAG_PNP_ROOT); @@ -178,6 +167,74 @@ PnpRootCreateDevice( Status = STATUS_NO_MEMORY; goto cleanup; } + + Status = IopOpenRegistryKeyEx(&EnumHandle, NULL, &EnumKeyName, KEY_READ); + if (NT_SUCCESS(Status)) + { + InitializeObjectAttributes(&ObjectAttributes, &Device->DeviceID, OBJ_CASE_INSENSITIVE, EnumHandle, NULL); + Status = ZwCreateKey(&DeviceKeyHandle, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, 0, NULL); + ZwClose(EnumHandle); + } + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to open registry key\n"); + goto cleanup; + } + +tryagain: + RtlZeroMemory(QueryTable, sizeof(QueryTable)); + QueryTable[0].Name = L"NextInstance"; + QueryTable[0].EntryContext = &NextInstance; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; + + Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE, + (PWSTR)DeviceKeyHandle, + QueryTable, + NULL, + NULL); + if (!NT_SUCCESS(Status)) + { + for (NextInstance = 0; NextInstance <= 9999; NextInstance++) + { + _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance); + Status = LocateChildDevice(DeviceExtension, DevicePath, InstancePath, &Device); + if (Status == STATUS_NO_SUCH_DEVICE) + break; + } + + if (NextInstance > 9999) + { + DPRINT1("Too many legacy devices reported for service '%wZ'\n", ServiceName); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + } + + _snwprintf(InstancePath, sizeof(InstancePath) / sizeof(WCHAR), L"%04lu", NextInstance); + Status = LocateChildDevice(DeviceExtension, DevicePath, InstancePath, &Device); + if (Status != STATUS_NO_SUCH_DEVICE || NextInstance > 9999) + { + DPRINT1("NextInstance value is corrupt! (%d)\n", NextInstance); + RtlDeleteRegistryValue(RTL_REGISTRY_HANDLE, + (PWSTR)DeviceKeyHandle, + L"NextInstance"); + goto tryagain; + } + + NextInstance++; + Status = RtlWriteRegistryValue(RTL_REGISTRY_HANDLE, + (PWSTR)DeviceKeyHandle, + L"NextInstance", + REG_DWORD, + &NextInstance, + sizeof(NextInstance)); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to write new NextInstance value! (0x%x)\n", Status); + goto cleanup; + } + if (!RtlCreateUnicodeString(&Device->InstanceID, InstancePath)) { Status = STATUS_NO_MEMORY; @@ -244,6 +301,8 @@ cleanup: RtlFreeUnicodeString(&Device->InstanceID); ExFreePoolWithTag(Device, TAG_PNP_ROOT); } + if (DeviceKeyHandle != INVALID_HANDLE_VALUE) + ZwClose(DeviceKeyHandle); return Status; } @@ -677,24 +736,27 @@ PnpRootFdoPnpControl( if (NT_SUCCESS(Status)) DeviceExtension->State = dsStarted; } - break; + + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; case IRP_MN_STOP_DEVICE: DPRINT("IRP_MJ_PNP / IRP_MN_STOP_DEVICE\n"); /* Root device cannot be stopped */ - Status = STATUS_NOT_SUPPORTED; - break; + Irp->IoStatus.Status = Status = STATUS_INVALID_DEVICE_REQUEST; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; default: DPRINT("IRP_MJ_PNP / Unknown minor function 0x%lx\n", IrpSp->MinorFunction); - Status = STATUS_NOT_IMPLEMENTED; break; } if (Status != STATUS_PENDING) { - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); } return Status; @@ -707,48 +769,25 @@ PdoQueryDeviceRelations( IN PIO_STACK_LOCATION IrpSp) { PDEVICE_RELATIONS Relations; - DEVICE_RELATION_TYPE RelationType; NTSTATUS Status = Irp->IoStatus.Status; - RelationType = IrpSp->Parameters.QueryDeviceRelations.Type; + if (IrpSp->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation) + return Status; - switch (RelationType) + DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n"); + Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS)); + if (!Relations) { - /* FIXME: remove */ - case BusRelations: - { - if (IoGetAttachedDevice(DeviceObject) != DeviceObject) - { - /* We're not alone in the stack */ - DPRINT1("PnP is misbehaving ; don't know how to handle IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n"); - } - break; - } - - case TargetDeviceRelation: - { - DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n"); - Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS)); - if (!Relations) - { - DPRINT("ExAllocatePoolWithTag() failed\n"); - Status = STATUS_NO_MEMORY; - } - else - { - ObReferenceObject(DeviceObject); - Relations->Count = 1; - Relations->Objects[0] = DeviceObject; - Status = STATUS_SUCCESS; - Irp->IoStatus.Information = (ULONG_PTR)Relations; - } - break; - } - - default: - { - DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / unknown relation type 0x%lx\n", RelationType); - } + DPRINT("ExAllocatePoolWithTag() failed\n"); + Status = STATUS_NO_MEMORY; + } + else + { + ObReferenceObject(DeviceObject); + Relations->Count = 1; + Relations->Objects[0] = DeviceObject; + Status = STATUS_SUCCESS; + Irp->IoStatus.Information = (ULONG_PTR)Relations; } return Status; @@ -786,35 +825,29 @@ PdoQueryResources( DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - if (DeviceExtension->DeviceInfo->ResourceList == NULL) - { - /* Create an empty resource list */ - ResourceList = ExAllocatePool(PagedPool, sizeof(CM_RESOURCE_LIST)); - if (!ResourceList) - return STATUS_NO_MEMORY; - - ResourceList->Count = 0; - - Irp->IoStatus.Information = (ULONG_PTR)ResourceList; - } - else + if (DeviceExtension->DeviceInfo->ResourceList) { /* Copy existing resource requirement list */ ResourceList = ExAllocatePool( PagedPool, - FIELD_OFFSET(CM_RESOURCE_LIST, List) + DeviceExtension->DeviceInfo->ResourceListSize); + DeviceExtension->DeviceInfo->ResourceListSize); if (!ResourceList) return STATUS_NO_MEMORY; - ResourceList->Count = 1; RtlCopyMemory( - &ResourceList->List, + ResourceList, DeviceExtension->DeviceInfo->ResourceList, DeviceExtension->DeviceInfo->ResourceListSize); - Irp->IoStatus.Information = (ULONG_PTR)ResourceList; - } - return STATUS_SUCCESS; + Irp->IoStatus.Information = (ULONG_PTR)ResourceList; + + return STATUS_SUCCESS; + } + else + { + /* No resources so just return without changing the status */ + return Irp->IoStatus.Status; + } } static NTSTATUS @@ -825,23 +858,10 @@ PdoQueryResourceRequirements( { PPNPROOT_PDO_DEVICE_EXTENSION DeviceExtension; PIO_RESOURCE_REQUIREMENTS_LIST ResourceList; - ULONG ResourceListSize = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List); DeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - if (DeviceExtension->DeviceInfo->ResourceRequirementsList == NULL) - { - /* Create an empty resource list */ - ResourceList = ExAllocatePool(PagedPool, ResourceListSize); - if (!ResourceList) - return STATUS_NO_MEMORY; - - RtlZeroMemory(ResourceList, ResourceListSize); - ResourceList->ListSize = ResourceListSize; - - Irp->IoStatus.Information = (ULONG_PTR)ResourceList; - } - else + if (DeviceExtension->DeviceInfo->ResourceRequirementsList) { /* Copy existing resource requirement list */ ResourceList = ExAllocatePool(PagedPool, DeviceExtension->DeviceInfo->ResourceRequirementsList->ListSize); @@ -852,10 +872,16 @@ PdoQueryResourceRequirements( ResourceList, DeviceExtension->DeviceInfo->ResourceRequirementsList, DeviceExtension->DeviceInfo->ResourceRequirementsList->ListSize); - Irp->IoStatus.Information = (ULONG_PTR)ResourceList; - } - return STATUS_SUCCESS; + Irp->IoStatus.Information = (ULONG_PTR)ResourceList; + + return STATUS_SUCCESS; + } + else + { + /* No resource requirements so just return without changing the status */ + return Irp->IoStatus.Status; + } } static NTSTATUS