+
+ 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;
+ }
+