Author: janderwald
Date: Fri Apr 2 16:01:55 2010
New Revision: 46681
URL:
http://svn.reactos.org/svn/reactos?rev=46681&view=rev
Log:
[NTOS]
- Add support for reference strings in IoOpenDeviceInterfaceRegistryKey
Modified:
trunk/reactos/ntoskrnl/io/iomgr/deviface.c
Modified: trunk/reactos/ntoskrnl/io/iomgr/deviface.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/deviface…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/deviface.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/deviface.c [iso-8859-1] Fri Apr 2 16:01:55 2010
@@ -51,31 +51,29 @@
OUT PHANDLE DeviceInterfaceKey)
{
WCHAR StrBuff[MAX_PATH], PathBuff[MAX_PATH];
- PWCHAR Guid;
- UNICODE_STRING EnumU = RTL_CONSTANT_STRING(ENUM_ROOT L"\\");
+ PWCHAR Guid, RefString;
UNICODE_STRING DevParamU = RTL_CONSTANT_STRING(L"\\Device Parameters");
UNICODE_STRING PrefixU = RTL_CONSTANT_STRING(L"\\??\\");
UNICODE_STRING KeyPath, KeyName;
UNICODE_STRING MatchableGuid;
- HANDLE GuidKey, ChildKey;
+ UNICODE_STRING GuidString;
+ HANDLE GuidKey, hInterfaceKey;
ULONG Index = 0;
PKEY_BASIC_INFORMATION KeyInformation;
ULONG KeyInformationLength;
- PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
- ULONG KeyValueInformationLength;
OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS Status;
ULONG RequiredLength;
- MatchableGuid.Length = 0;
- MatchableGuid.Length += swprintf(StrBuff,
- L"##?#%ls",
- &SymbolicLinkName->Buffer[PrefixU.Length /
sizeof(WCHAR)]);
- StrBuff[++MatchableGuid.Length] = UNICODE_NULL;
-
- MatchableGuid.Buffer = StrBuff;
- MatchableGuid.MaximumLength = MAX_PATH * sizeof(WCHAR);
- MatchableGuid.Length = (MatchableGuid.Length-1) * sizeof(WCHAR);
+ swprintf(StrBuff, L"##?#%s",
&SymbolicLinkName->Buffer[PrefixU.Length / sizeof(WCHAR)]);
+
+ RefString = wcsstr(StrBuff, L"\\");
+ if (RefString)
+ {
+ RefString[0] = 0;
+ }
+
+ RtlInitUnicodeString(&MatchableGuid, StrBuff);
Guid = wcsstr(StrBuff, L"{");
if (!Guid)
@@ -85,8 +83,11 @@
KeyPath.Length = 0;
KeyPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
+ GuidString.Buffer = Guid;
+ GuidString.Length = GuidString.MaximumLength = 38 * sizeof(WCHAR);
+
RtlAppendUnicodeToString(&KeyPath, BaseKeyString);
- RtlAppendUnicodeToString(&KeyPath, Guid);
+ RtlAppendUnicodeStringToString(&KeyPath, &GuidString);
InitializeObjectAttributes(&ObjectAttributes,
&KeyPath,
@@ -142,73 +143,62 @@
KeyName.Buffer = KeyInformation->Name;
if (!RtlEqualUnicodeString(&KeyName, &MatchableGuid, TRUE))
+ {
+ ExFreePool(KeyInformation);
continue;
-
+ }
+
+ KeyPath.Length = 0;
+ RtlAppendUnicodeStringToString(&KeyPath, &KeyName);
+ RtlAppendUnicodeToString(&KeyPath, L"\\");
+
+ /* check for presence of a reference string */
+ if (RefString)
+ {
+ /* append reference string */
+ RefString[0] = L'#';
+ RtlInitUnicodeString(&KeyName, RefString);
+ }
+ else
+ {
+ /* no reference string */
+ RtlInitUnicodeString(&KeyName, L"#");
+ }
+ RtlAppendUnicodeStringToString(&KeyPath, &KeyName);
+
+ /* initialize reference string attributes */
InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
+ &KeyPath,
OBJ_CASE_INSENSITIVE,
GuidKey,
NULL);
- Status = ZwOpenKey(&ChildKey, KEY_QUERY_VALUE, &ObjectAttributes);
+
+ /* 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);
- 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,
- &KeyName,
- KeyValuePartialInformation,
- KeyValueInformation,
- KeyValueInformationLength,
- &RequiredLength);
- }
- else
- {
- ZwClose(ChildKey);
- return STATUS_OBJECT_PATH_NOT_FOUND;
- }
- 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, &DevParamU);
-
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyPath,
- OBJ_CASE_INSENSITIVE,
- 0,
- NULL);
- Status = ZwCreateKey(DeviceInterfaceKey,
- DesiredAccess,
- &ObjectAttributes,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- NULL);
+ ExFreePool(KeyInformation);
return Status;
}