mirror of
https://github.com/reactos/reactos.git
synced 2025-07-04 13:11:33 +00:00
[NTOS]
- Add support for reference strings in IoOpenDeviceInterfaceRegistryKey svn path=/trunk/; revision=46681
This commit is contained in:
parent
90a11f48e9
commit
95650313d9
1 changed files with 59 additions and 69 deletions
|
@ -51,31 +51,29 @@ IoOpenDeviceInterfaceRegistryKey(IN PUNICODE_STRING SymbolicLinkName,
|
||||||
OUT PHANDLE DeviceInterfaceKey)
|
OUT PHANDLE DeviceInterfaceKey)
|
||||||
{
|
{
|
||||||
WCHAR StrBuff[MAX_PATH], PathBuff[MAX_PATH];
|
WCHAR StrBuff[MAX_PATH], PathBuff[MAX_PATH];
|
||||||
PWCHAR Guid;
|
PWCHAR Guid, RefString;
|
||||||
UNICODE_STRING EnumU = RTL_CONSTANT_STRING(ENUM_ROOT L"\\");
|
|
||||||
UNICODE_STRING DevParamU = RTL_CONSTANT_STRING(L"\\Device Parameters");
|
UNICODE_STRING DevParamU = RTL_CONSTANT_STRING(L"\\Device Parameters");
|
||||||
UNICODE_STRING PrefixU = RTL_CONSTANT_STRING(L"\\??\\");
|
UNICODE_STRING PrefixU = RTL_CONSTANT_STRING(L"\\??\\");
|
||||||
UNICODE_STRING KeyPath, KeyName;
|
UNICODE_STRING KeyPath, KeyName;
|
||||||
UNICODE_STRING MatchableGuid;
|
UNICODE_STRING MatchableGuid;
|
||||||
HANDLE GuidKey, ChildKey;
|
UNICODE_STRING GuidString;
|
||||||
|
HANDLE GuidKey, hInterfaceKey;
|
||||||
ULONG Index = 0;
|
ULONG Index = 0;
|
||||||
PKEY_BASIC_INFORMATION KeyInformation;
|
PKEY_BASIC_INFORMATION KeyInformation;
|
||||||
ULONG KeyInformationLength;
|
ULONG KeyInformationLength;
|
||||||
PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
|
|
||||||
ULONG KeyValueInformationLength;
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG RequiredLength;
|
ULONG RequiredLength;
|
||||||
|
|
||||||
MatchableGuid.Length = 0;
|
swprintf(StrBuff, L"##?#%s", &SymbolicLinkName->Buffer[PrefixU.Length / sizeof(WCHAR)]);
|
||||||
MatchableGuid.Length += swprintf(StrBuff,
|
|
||||||
L"##?#%ls",
|
|
||||||
&SymbolicLinkName->Buffer[PrefixU.Length / sizeof(WCHAR)]);
|
|
||||||
StrBuff[++MatchableGuid.Length] = UNICODE_NULL;
|
|
||||||
|
|
||||||
MatchableGuid.Buffer = StrBuff;
|
RefString = wcsstr(StrBuff, L"\\");
|
||||||
MatchableGuid.MaximumLength = MAX_PATH * sizeof(WCHAR);
|
if (RefString)
|
||||||
MatchableGuid.Length = (MatchableGuid.Length-1) * sizeof(WCHAR);
|
{
|
||||||
|
RefString[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&MatchableGuid, StrBuff);
|
||||||
|
|
||||||
Guid = wcsstr(StrBuff, L"{");
|
Guid = wcsstr(StrBuff, L"{");
|
||||||
if (!Guid)
|
if (!Guid)
|
||||||
|
@ -85,8 +83,11 @@ IoOpenDeviceInterfaceRegistryKey(IN PUNICODE_STRING SymbolicLinkName,
|
||||||
KeyPath.Length = 0;
|
KeyPath.Length = 0;
|
||||||
KeyPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
|
KeyPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
|
||||||
|
|
||||||
|
GuidString.Buffer = Guid;
|
||||||
|
GuidString.Length = GuidString.MaximumLength = 38 * sizeof(WCHAR);
|
||||||
|
|
||||||
RtlAppendUnicodeToString(&KeyPath, BaseKeyString);
|
RtlAppendUnicodeToString(&KeyPath, BaseKeyString);
|
||||||
RtlAppendUnicodeToString(&KeyPath, Guid);
|
RtlAppendUnicodeStringToString(&KeyPath, &GuidString);
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
&KeyPath,
|
&KeyPath,
|
||||||
|
@ -142,73 +143,62 @@ IoOpenDeviceInterfaceRegistryKey(IN PUNICODE_STRING SymbolicLinkName,
|
||||||
KeyName.Buffer = KeyInformation->Name;
|
KeyName.Buffer = KeyInformation->Name;
|
||||||
|
|
||||||
if (!RtlEqualUnicodeString(&KeyName, &MatchableGuid, TRUE))
|
if (!RtlEqualUnicodeString(&KeyName, &MatchableGuid, TRUE))
|
||||||
|
{
|
||||||
|
ExFreePool(KeyInformation);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
|
||||||
&KeyName,
|
|
||||||
OBJ_CASE_INSENSITIVE,
|
|
||||||
GuidKey,
|
|
||||||
NULL);
|
|
||||||
Status = ZwOpenKey(&ChildKey, KEY_QUERY_VALUE, &ObjectAttributes);
|
|
||||||
ZwClose(GuidKey);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
return Status;
|
|
||||||
|
|
||||||
RtlInitUnicodeString(&KeyName, L"DeviceInstance");
|
|
||||||
Status = ZwQueryValueKey(ChildKey,
|
|
||||||
&KeyName,
|
|
||||||
KeyValuePartialInformation,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
&RequiredLength);
|
|
||||||
if (Status == STATUS_BUFFER_TOO_SMALL)
|
|
||||||
{
|
|
||||||
KeyValueInformationLength = RequiredLength;
|
|
||||||
KeyValueInformation = ExAllocatePool(PagedPool, KeyValueInformationLength);
|
|
||||||
if (!KeyValueInformation)
|
|
||||||
{
|
|
||||||
ZwClose(ChildKey);
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ZwQueryValueKey(ChildKey,
|
KeyPath.Length = 0;
|
||||||
&KeyName,
|
RtlAppendUnicodeStringToString(&KeyPath, &KeyName);
|
||||||
KeyValuePartialInformation,
|
RtlAppendUnicodeToString(&KeyPath, L"\\");
|
||||||
KeyValueInformation,
|
|
||||||
KeyValueInformationLength,
|
/* check for presence of a reference string */
|
||||||
&RequiredLength);
|
if (RefString)
|
||||||
|
{
|
||||||
|
/* append reference string */
|
||||||
|
RefString[0] = L'#';
|
||||||
|
RtlInitUnicodeString(&KeyName, RefString);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ZwClose(ChildKey);
|
/* no reference string */
|
||||||
return STATUS_OBJECT_PATH_NOT_FOUND;
|
RtlInitUnicodeString(&KeyName, L"#");
|
||||||
}
|
}
|
||||||
ZwClose(ChildKey);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
return Status;
|
|
||||||
|
|
||||||
KeyPath.Length = 0;
|
|
||||||
|
|
||||||
KeyName.Length = KeyName.MaximumLength = KeyValueInformation->DataLength;
|
|
||||||
KeyName.Buffer = (PWCHAR)KeyValueInformation->Data;
|
|
||||||
|
|
||||||
RtlAppendUnicodeStringToString(&KeyPath, &EnumU);
|
|
||||||
RtlAppendUnicodeStringToString(&KeyPath, &KeyName);
|
RtlAppendUnicodeStringToString(&KeyPath, &KeyName);
|
||||||
RtlAppendUnicodeStringToString(&KeyPath, &DevParamU);
|
|
||||||
|
|
||||||
|
/* initialize reference string attributes */
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
&KeyPath,
|
&KeyPath,
|
||||||
OBJ_CASE_INSENSITIVE,
|
OBJ_CASE_INSENSITIVE,
|
||||||
0,
|
GuidKey,
|
||||||
NULL);
|
|
||||||
Status = ZwCreateKey(DeviceInterfaceKey,
|
|
||||||
DesiredAccess,
|
|
||||||
&ObjectAttributes,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
REG_OPTION_NON_VOLATILE,
|
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
/* now open device interface key */
|
||||||
|
Status = ZwOpenKey(&hInterfaceKey, KEY_CREATE_SUB_KEY, &ObjectAttributes);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* check if it provides a DeviceParameters key */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, &DevParamU, OBJ_CASE_INSENSITIVE, hInterfaceKey, NULL);
|
||||||
|
|
||||||
|
Status = ZwCreateKey(DeviceInterfaceKey, DesiredAccess, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* DeviceParameters key present */
|
||||||
|
ZwClose(hInterfaceKey);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* fall back to device interface */
|
||||||
|
*DeviceInterfaceKey = hInterfaceKey;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* close class key */
|
||||||
|
ZwClose(GuidKey);
|
||||||
|
ExFreePool(KeyInformation);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue