mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
- Make IoGetDeviceInterfaces more compatible with the native version. Patch by Matthew Brace.
svn path=/trunk/; revision=8701
This commit is contained in:
parent
89265e0151
commit
b0b55220e6
1 changed files with 247 additions and 159 deletions
|
@ -18,6 +18,7 @@ DEFINE_GUID(GUID_SERENUM_BUS_ENUMERATOR, 0x4D36E978L, 0xE325, 0x11CE, 0xBF, 0xC1
|
|||
#endif
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
#define ASSERT assert
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
|
@ -99,13 +100,16 @@ IoGetDeviceInterfaces(
|
|||
UNICODE_STRING BaseKeyName;
|
||||
UNICODE_STRING AliasKeyName;
|
||||
UNICODE_STRING SymbolicLink;
|
||||
UNICODE_STRING Control;
|
||||
UNICODE_STRING SubKeyName;
|
||||
UNICODE_STRING SymbolicLinkKeyName;
|
||||
UNICODE_STRING ControlKeyName;
|
||||
UNICODE_STRING TempString;
|
||||
HANDLE InterfaceKey;
|
||||
HANDLE SubKey;
|
||||
HANDLE SymbolicLinkKey;
|
||||
PKEY_FULL_INFORMATION fip;
|
||||
PKEY_FULL_INFORMATION bfip;
|
||||
PKEY_BASIC_INFORMATION bip;
|
||||
PKEY_VALUE_PARTIAL_INFORMATION vpip;
|
||||
PWCHAR SymLinkList = NULL;
|
||||
|
@ -113,6 +117,7 @@ IoGetDeviceInterfaces(
|
|||
NTSTATUS Status;
|
||||
ULONG Size = 0;
|
||||
ULONG i = 0;
|
||||
ULONG j = 0;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
|
||||
Status = RtlStringFromGUID(InterfaceClassGuid, &GuidString);
|
||||
|
@ -124,18 +129,19 @@ IoGetDeviceInterfaces(
|
|||
|
||||
RtlInitUnicodeString(&AliasKeyName, BaseInterfaceString);
|
||||
RtlInitUnicodeString(&SymbolicLink, L"SymbolicLink");
|
||||
RtlInitUnicodeString(&Control, L"\\Control");
|
||||
BaseKeyName.Length = wcslen(BaseKeyString) * sizeof(WCHAR);
|
||||
BaseKeyName.MaximumLength = BaseKeyName.Length + (38 * sizeof(WCHAR));
|
||||
BaseKeyName.Buffer = ExAllocatePool(
|
||||
NonPagedPool,
|
||||
BaseKeyName.MaximumLength);
|
||||
assert(BaseKeyName.Buffer != NULL);
|
||||
ASSERT(BaseKeyName.Buffer != NULL);
|
||||
wcscpy(BaseKeyName.Buffer, BaseKeyString);
|
||||
RtlAppendUnicodeStringToString(&BaseKeyName, &GuidString);
|
||||
|
||||
if (PhysicalDeviceObject)
|
||||
{
|
||||
WCHAR GuidBuffer[32];
|
||||
WCHAR GuidBuffer[40];
|
||||
UNICODE_STRING PdoGuidString;
|
||||
|
||||
RtlFreeUnicodeString(&BaseKeyName);
|
||||
|
@ -194,7 +200,7 @@ IoGetDeviceInterfaces(
|
|||
}
|
||||
|
||||
fip = (PKEY_FULL_INFORMATION)ExAllocatePool(NonPagedPool, Size);
|
||||
assert(fip != NULL);
|
||||
ASSERT(fip != NULL);
|
||||
|
||||
Status = ZwQueryKey(
|
||||
InterfaceKey,
|
||||
|
@ -234,7 +240,7 @@ IoGetDeviceInterfaces(
|
|||
}
|
||||
|
||||
bip = (PKEY_BASIC_INFORMATION)ExAllocatePool(NonPagedPool, Size);
|
||||
assert(bip != NULL);
|
||||
ASSERT(bip != NULL);
|
||||
|
||||
Status = ZwEnumerateKey(
|
||||
InterfaceKey,
|
||||
|
@ -259,7 +265,7 @@ IoGetDeviceInterfaces(
|
|||
SubKeyName.Length = 0;
|
||||
SubKeyName.MaximumLength = BaseKeyName.Length + bip->NameLength + sizeof(WCHAR);
|
||||
SubKeyName.Buffer = ExAllocatePool(NonPagedPool, SubKeyName.MaximumLength);
|
||||
assert(SubKeyName.Buffer != NULL);
|
||||
ASSERT(SubKeyName.Buffer != NULL);
|
||||
TempString.Length = TempString.MaximumLength = bip->NameLength;
|
||||
TempString.Buffer = bip->Name;
|
||||
RtlCopyUnicodeString(&SubKeyName, &BaseKeyName);
|
||||
|
@ -292,17 +298,62 @@ IoGetDeviceInterfaces(
|
|||
return Status;
|
||||
}
|
||||
|
||||
Status = ZwEnumerateKey(
|
||||
Status = ZwQueryKey(
|
||||
SubKey,
|
||||
0,
|
||||
KeyBasicInformation,
|
||||
KeyFullInformation,
|
||||
NULL,
|
||||
0,
|
||||
&Size);
|
||||
|
||||
if (Status != STATUS_BUFFER_TOO_SMALL)
|
||||
{
|
||||
DPRINT("ZwQueryKey() Failed. (0x%X)\n", Status);
|
||||
ExFreePool(fip);
|
||||
RtlFreeUnicodeString(&BaseKeyName);
|
||||
RtlFreeUnicodeString(&SubKeyName);
|
||||
ZwClose(SubKey);
|
||||
ZwClose(InterfaceKey);
|
||||
return Status;
|
||||
}
|
||||
|
||||
bfip = (PKEY_FULL_INFORMATION)ExAllocatePool(NonPagedPool, Size);
|
||||
ASSERT(bfip != NULL);
|
||||
|
||||
Status = ZwQueryKey(
|
||||
SubKey,
|
||||
KeyFullInformation,
|
||||
bfip,
|
||||
Size,
|
||||
&Size);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwQueryKey() Failed. (0x%X)\n", Status);
|
||||
ExFreePool(fip);
|
||||
RtlFreeUnicodeString(&SubKeyName);
|
||||
RtlFreeUnicodeString(&BaseKeyName);
|
||||
ZwClose(SubKey);
|
||||
ZwClose(InterfaceKey);
|
||||
return Status;
|
||||
}
|
||||
|
||||
for(j = 0; j < bfip->SubKeys; j++)
|
||||
{
|
||||
Status = ZwEnumerateKey(
|
||||
SubKey,
|
||||
j,
|
||||
KeyBasicInformation,
|
||||
NULL,
|
||||
0,
|
||||
&Size);
|
||||
|
||||
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||
continue;
|
||||
|
||||
if (Status != STATUS_BUFFER_TOO_SMALL)
|
||||
{
|
||||
DPRINT("ZwEnumerateKey() Failed.(0x%X)\n", Status);
|
||||
ExFreePool(bfip);
|
||||
ExFreePool(fip);
|
||||
if (SymLinkList != NULL)
|
||||
ExFreePool(SymLinkList);
|
||||
|
@ -314,11 +365,11 @@ IoGetDeviceInterfaces(
|
|||
}
|
||||
|
||||
bip = (PKEY_BASIC_INFORMATION)ExAllocatePool(NonPagedPool, Size);
|
||||
assert(bip != NULL);
|
||||
ASSERT(bip != NULL);
|
||||
|
||||
Status = ZwEnumerateKey(
|
||||
SubKey,
|
||||
0,
|
||||
j,
|
||||
KeyBasicInformation,
|
||||
bip,
|
||||
Size,
|
||||
|
@ -328,6 +379,7 @@ IoGetDeviceInterfaces(
|
|||
{
|
||||
DPRINT("ZwEnumerateKey() Failed.(0x%X)\n", Status);
|
||||
ExFreePool(fip);
|
||||
ExFreePool(bfip);
|
||||
ExFreePool(bip);
|
||||
if (SymLinkList != NULL)
|
||||
ExFreePool(SymLinkList);
|
||||
|
@ -338,16 +390,28 @@ IoGetDeviceInterfaces(
|
|||
return Status;
|
||||
}
|
||||
|
||||
if (!wcsncmp(bip->Name, L"Control", bip->NameLength))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
SymbolicLinkKeyName.Length = 0;
|
||||
SymbolicLinkKeyName.MaximumLength = SubKeyName.Length + bip->NameLength + sizeof(WCHAR);
|
||||
SymbolicLinkKeyName.Buffer = ExAllocatePool(NonPagedPool, SymbolicLinkKeyName.MaximumLength);
|
||||
assert(SymbolicLinkKeyName.Buffer != NULL);
|
||||
ASSERT(SymbolicLinkKeyName.Buffer != NULL);
|
||||
TempString.Length = TempString.MaximumLength = bip->NameLength;
|
||||
TempString.Buffer = bip->Name;
|
||||
RtlCopyUnicodeString(&SymbolicLinkKeyName, &SubKeyName);
|
||||
RtlAppendUnicodeToString(&SymbolicLinkKeyName, L"\\");
|
||||
RtlAppendUnicodeStringToString(&SymbolicLinkKeyName, &TempString);
|
||||
|
||||
ControlKeyName.Length = 0;
|
||||
ControlKeyName.MaximumLength = SymbolicLinkKeyName.Length + Control.Length + sizeof(WCHAR);
|
||||
ControlKeyName.Buffer = ExAllocatePool(NonPagedPool, ControlKeyName.MaximumLength);
|
||||
ASSERT(ControlKeyName.Buffer != NULL);
|
||||
RtlCopyUnicodeString(&ControlKeyName, &SymbolicLinkKeyName);
|
||||
RtlAppendUnicodeStringToString(&ControlKeyName, &Control);
|
||||
|
||||
ExFreePool(bip);
|
||||
|
||||
InitializeObjectAttributes(
|
||||
|
@ -366,6 +430,7 @@ IoGetDeviceInterfaces(
|
|||
{
|
||||
DPRINT("ZwOpenKey() Failed. (0x%X)\n", Status);
|
||||
ExFreePool(fip);
|
||||
ExFreePool(bfip);
|
||||
if (SymLinkList != NULL)
|
||||
ExFreePool(SymLinkList);
|
||||
RtlFreeUnicodeString(&SymbolicLinkKeyName);
|
||||
|
@ -384,10 +449,14 @@ IoGetDeviceInterfaces(
|
|||
0,
|
||||
&Size);
|
||||
|
||||
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||
continue;
|
||||
|
||||
if (Status != STATUS_BUFFER_TOO_SMALL)
|
||||
{
|
||||
DPRINT("ZwQueryValueKey() Failed.(0x%X)\n", Status);
|
||||
ExFreePool(fip);
|
||||
ExFreePool(bfip);
|
||||
if (SymLinkList != NULL)
|
||||
ExFreePool(SymLinkList);
|
||||
RtlFreeUnicodeString(&SymbolicLinkKeyName);
|
||||
|
@ -400,7 +469,7 @@ IoGetDeviceInterfaces(
|
|||
}
|
||||
|
||||
vpip = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePool(NonPagedPool, Size);
|
||||
assert(vpip != NULL);
|
||||
ASSERT(vpip != NULL);
|
||||
|
||||
Status = ZwQueryValueKey(
|
||||
SymbolicLinkKey,
|
||||
|
@ -412,7 +481,9 @@ IoGetDeviceInterfaces(
|
|||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwQueryValueKey() Failed.(0x%X)\n", Status);
|
||||
ExFreePool(fip);
|
||||
ExFreePool(bfip);
|
||||
ExFreePool(vpip);
|
||||
if (SymLinkList != NULL)
|
||||
ExFreePool(SymLinkList);
|
||||
|
@ -425,12 +496,16 @@ IoGetDeviceInterfaces(
|
|||
return Status;
|
||||
}
|
||||
|
||||
Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, ControlKeyName.Buffer);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Put the name in the string here */
|
||||
if (SymLinkList == NULL)
|
||||
{
|
||||
SymLinkListSize = vpip->DataLength;
|
||||
SymLinkList = ExAllocatePool(NonPagedPool, SymLinkListSize + sizeof(WCHAR));
|
||||
assert(SymLinkList != NULL);
|
||||
ASSERT(SymLinkList != NULL);
|
||||
RtlCopyMemory(SymLinkList, vpip->Data, vpip->DataLength);
|
||||
SymLinkList[vpip->DataLength / sizeof(WCHAR)] = 0;
|
||||
SymLinkList[1] = '?';
|
||||
|
@ -445,7 +520,7 @@ IoGetDeviceInterfaces(
|
|||
OldSymLinkListSize = SymLinkListSize;
|
||||
SymLinkListSize += vpip->DataLength;
|
||||
SymLinkList = ExAllocatePool(NonPagedPool, SymLinkListSize + sizeof(WCHAR));
|
||||
assert(SymLinkList != NULL);
|
||||
ASSERT(SymLinkList != NULL);
|
||||
RtlCopyMemory(SymLinkList, OldSymLinkList, OldSymLinkListSize);
|
||||
ExFreePool(OldSymLinkList);
|
||||
SymLinkListPtr = SymLinkList + (OldSymLinkListSize / sizeof(WCHAR));
|
||||
|
@ -453,20 +528,33 @@ IoGetDeviceInterfaces(
|
|||
SymLinkListPtr[vpip->DataLength / sizeof(WCHAR)] = 0;
|
||||
SymLinkListPtr[1] = '?';
|
||||
}
|
||||
}
|
||||
|
||||
RtlFreeUnicodeString(&SymbolicLinkKeyName);
|
||||
RtlFreeUnicodeString(&SubKeyName);
|
||||
RtlFreeUnicodeString(&ControlKeyName);
|
||||
ZwClose(SymbolicLinkKey);
|
||||
ZwClose(SubKey);
|
||||
}
|
||||
|
||||
ExFreePool(vpip);
|
||||
RtlFreeUnicodeString(&SubKeyName);
|
||||
ZwClose(SubKey);
|
||||
}
|
||||
|
||||
if (SymLinkList != NULL)
|
||||
{
|
||||
SymLinkList[SymLinkListSize / sizeof(WCHAR)] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
SymLinkList = ExAllocatePool(NonPagedPool, 2 * sizeof(WCHAR));
|
||||
SymLinkList[0] = 0;
|
||||
}
|
||||
|
||||
*SymbolicLinkList = SymLinkList;
|
||||
|
||||
RtlFreeUnicodeString(&BaseKeyName);
|
||||
ZwClose(InterfaceKey);
|
||||
ExFreePool(bfip);
|
||||
ExFreePool(fip);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue