mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 03:15:43 +00:00
[NTOSKRNL]
- Cache the next instance value in the the registry so we don't have to go searching for an unused instance number every time we add a new device svn path=/trunk/; revision=46808
This commit is contained in:
parent
aca1c8384f
commit
f3683186aa
1 changed files with 75 additions and 15 deletions
|
@ -139,29 +139,19 @@ PnpRootCreateDevice(
|
||||||
WCHAR InstancePath[5];
|
WCHAR InstancePath[5];
|
||||||
PPNPROOT_DEVICE Device = NULL;
|
PPNPROOT_DEVICE Device = NULL;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG i;
|
|
||||||
UNICODE_STRING PathSep = RTL_CONSTANT_STRING(L"\\");
|
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;
|
DeviceExtension = PnpRootDeviceObject->DeviceExtension;
|
||||||
KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
|
KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
|
||||||
|
|
||||||
DPRINT("Creating a PnP root device for service '%wZ'\n", ServiceName);
|
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);
|
_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 */
|
/* Initialize a PNPROOT_DEVICE structure */
|
||||||
Device = ExAllocatePoolWithTag(PagedPool, sizeof(PNPROOT_DEVICE), TAG_PNP_ROOT);
|
Device = ExAllocatePoolWithTag(PagedPool, sizeof(PNPROOT_DEVICE), TAG_PNP_ROOT);
|
||||||
|
@ -177,6 +167,74 @@ PnpRootCreateDevice(
|
||||||
Status = STATUS_NO_MEMORY;
|
Status = STATUS_NO_MEMORY;
|
||||||
goto cleanup;
|
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))
|
if (!RtlCreateUnicodeString(&Device->InstanceID, InstancePath))
|
||||||
{
|
{
|
||||||
Status = STATUS_NO_MEMORY;
|
Status = STATUS_NO_MEMORY;
|
||||||
|
@ -243,6 +301,8 @@ cleanup:
|
||||||
RtlFreeUnicodeString(&Device->InstanceID);
|
RtlFreeUnicodeString(&Device->InstanceID);
|
||||||
ExFreePoolWithTag(Device, TAG_PNP_ROOT);
|
ExFreePoolWithTag(Device, TAG_PNP_ROOT);
|
||||||
}
|
}
|
||||||
|
if (DeviceKeyHandle != INVALID_HANDLE_VALUE)
|
||||||
|
ZwClose(DeviceKeyHandle);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue