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
|
#endif
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
#define ASSERT assert
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
@ -99,13 +100,16 @@ IoGetDeviceInterfaces(
|
||||||
UNICODE_STRING BaseKeyName;
|
UNICODE_STRING BaseKeyName;
|
||||||
UNICODE_STRING AliasKeyName;
|
UNICODE_STRING AliasKeyName;
|
||||||
UNICODE_STRING SymbolicLink;
|
UNICODE_STRING SymbolicLink;
|
||||||
|
UNICODE_STRING Control;
|
||||||
UNICODE_STRING SubKeyName;
|
UNICODE_STRING SubKeyName;
|
||||||
UNICODE_STRING SymbolicLinkKeyName;
|
UNICODE_STRING SymbolicLinkKeyName;
|
||||||
|
UNICODE_STRING ControlKeyName;
|
||||||
UNICODE_STRING TempString;
|
UNICODE_STRING TempString;
|
||||||
HANDLE InterfaceKey;
|
HANDLE InterfaceKey;
|
||||||
HANDLE SubKey;
|
HANDLE SubKey;
|
||||||
HANDLE SymbolicLinkKey;
|
HANDLE SymbolicLinkKey;
|
||||||
PKEY_FULL_INFORMATION fip;
|
PKEY_FULL_INFORMATION fip;
|
||||||
|
PKEY_FULL_INFORMATION bfip;
|
||||||
PKEY_BASIC_INFORMATION bip;
|
PKEY_BASIC_INFORMATION bip;
|
||||||
PKEY_VALUE_PARTIAL_INFORMATION vpip;
|
PKEY_VALUE_PARTIAL_INFORMATION vpip;
|
||||||
PWCHAR SymLinkList = NULL;
|
PWCHAR SymLinkList = NULL;
|
||||||
|
@ -113,6 +117,7 @@ IoGetDeviceInterfaces(
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG Size = 0;
|
ULONG Size = 0;
|
||||||
ULONG i = 0;
|
ULONG i = 0;
|
||||||
|
ULONG j = 0;
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
|
||||||
Status = RtlStringFromGUID(InterfaceClassGuid, &GuidString);
|
Status = RtlStringFromGUID(InterfaceClassGuid, &GuidString);
|
||||||
|
@ -124,33 +129,34 @@ IoGetDeviceInterfaces(
|
||||||
|
|
||||||
RtlInitUnicodeString(&AliasKeyName, BaseInterfaceString);
|
RtlInitUnicodeString(&AliasKeyName, BaseInterfaceString);
|
||||||
RtlInitUnicodeString(&SymbolicLink, L"SymbolicLink");
|
RtlInitUnicodeString(&SymbolicLink, L"SymbolicLink");
|
||||||
|
RtlInitUnicodeString(&Control, L"\\Control");
|
||||||
BaseKeyName.Length = wcslen(BaseKeyString) * sizeof(WCHAR);
|
BaseKeyName.Length = wcslen(BaseKeyString) * sizeof(WCHAR);
|
||||||
BaseKeyName.MaximumLength = BaseKeyName.Length + (38 * sizeof(WCHAR));
|
BaseKeyName.MaximumLength = BaseKeyName.Length + (38 * sizeof(WCHAR));
|
||||||
BaseKeyName.Buffer = ExAllocatePool(
|
BaseKeyName.Buffer = ExAllocatePool(
|
||||||
NonPagedPool,
|
NonPagedPool,
|
||||||
BaseKeyName.MaximumLength);
|
BaseKeyName.MaximumLength);
|
||||||
assert(BaseKeyName.Buffer != NULL);
|
ASSERT(BaseKeyName.Buffer != NULL);
|
||||||
wcscpy(BaseKeyName.Buffer, BaseKeyString);
|
wcscpy(BaseKeyName.Buffer, BaseKeyString);
|
||||||
RtlAppendUnicodeStringToString(&BaseKeyName, &GuidString);
|
RtlAppendUnicodeStringToString(&BaseKeyName, &GuidString);
|
||||||
|
|
||||||
if (PhysicalDeviceObject)
|
if (PhysicalDeviceObject)
|
||||||
{
|
{
|
||||||
WCHAR GuidBuffer[32];
|
WCHAR GuidBuffer[40];
|
||||||
UNICODE_STRING PdoGuidString;
|
UNICODE_STRING PdoGuidString;
|
||||||
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
RtlFreeUnicodeString(&BaseKeyName);
|
||||||
|
|
||||||
IoGetDeviceProperty(
|
IoGetDeviceProperty(
|
||||||
PhysicalDeviceObject,
|
PhysicalDeviceObject,
|
||||||
DevicePropertyClassGuid,
|
DevicePropertyClassGuid,
|
||||||
sizeof(GuidBuffer),
|
sizeof(GuidBuffer),
|
||||||
GuidBuffer,
|
GuidBuffer,
|
||||||
&Size);
|
&Size);
|
||||||
|
|
||||||
RtlInitUnicodeString(&PdoGuidString, GuidBuffer);
|
RtlInitUnicodeString(&PdoGuidString, GuidBuffer);
|
||||||
if (RtlCompareUnicodeString(&GuidString, &PdoGuidString, TRUE))
|
if (RtlCompareUnicodeString(&GuidString, &PdoGuidString, TRUE))
|
||||||
{
|
{
|
||||||
DPRINT("Inconsistent Guid's asked for in IoGetDeviceInterfaces()\n");
|
DPRINT("Inconsistent Guid's asked for in IoGetDeviceInterfaces()\n");
|
||||||
return STATUS_INVALID_HANDLE;
|
return STATUS_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +186,7 @@ IoGetDeviceInterfaces(
|
||||||
|
|
||||||
Status = ZwQueryKey(
|
Status = ZwQueryKey(
|
||||||
InterfaceKey,
|
InterfaceKey,
|
||||||
KeyFullInformation,
|
KeyFullInformation,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
&Size);
|
&Size);
|
||||||
|
@ -194,14 +200,14 @@ IoGetDeviceInterfaces(
|
||||||
}
|
}
|
||||||
|
|
||||||
fip = (PKEY_FULL_INFORMATION)ExAllocatePool(NonPagedPool, Size);
|
fip = (PKEY_FULL_INFORMATION)ExAllocatePool(NonPagedPool, Size);
|
||||||
assert(fip != NULL);
|
ASSERT(fip != NULL);
|
||||||
|
|
||||||
Status = ZwQueryKey(
|
Status = ZwQueryKey(
|
||||||
InterfaceKey,
|
InterfaceKey,
|
||||||
KeyFullInformation,
|
KeyFullInformation,
|
||||||
fip,
|
fip,
|
||||||
Size,
|
Size,
|
||||||
&Size);
|
&Size);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -216,15 +222,15 @@ IoGetDeviceInterfaces(
|
||||||
{
|
{
|
||||||
Status = ZwEnumerateKey(
|
Status = ZwEnumerateKey(
|
||||||
InterfaceKey,
|
InterfaceKey,
|
||||||
i,
|
i,
|
||||||
KeyBasicInformation,
|
KeyBasicInformation,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
&Size);
|
&Size);
|
||||||
|
|
||||||
if (Status != STATUS_BUFFER_TOO_SMALL)
|
if (Status != STATUS_BUFFER_TOO_SMALL)
|
||||||
{
|
{
|
||||||
DPRINT("ZwEnumerateKey() Failed. (0x%X)\n", Status);
|
DPRINT("ZwEnumerateKey() Failed.(0x%X)\n", Status);
|
||||||
ExFreePool(fip);
|
ExFreePool(fip);
|
||||||
if (SymLinkList != NULL)
|
if (SymLinkList != NULL)
|
||||||
ExFreePool(SymLinkList);
|
ExFreePool(SymLinkList);
|
||||||
|
@ -234,7 +240,7 @@ IoGetDeviceInterfaces(
|
||||||
}
|
}
|
||||||
|
|
||||||
bip = (PKEY_BASIC_INFORMATION)ExAllocatePool(NonPagedPool, Size);
|
bip = (PKEY_BASIC_INFORMATION)ExAllocatePool(NonPagedPool, Size);
|
||||||
assert(bip != NULL);
|
ASSERT(bip != NULL);
|
||||||
|
|
||||||
Status = ZwEnumerateKey(
|
Status = ZwEnumerateKey(
|
||||||
InterfaceKey,
|
InterfaceKey,
|
||||||
|
@ -246,7 +252,7 @@ IoGetDeviceInterfaces(
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("ZwEnumerateKey() Failed. (0x%X)\n", Status);
|
DPRINT("ZwEnumerateKey() Failed.(0x%X)\n", Status);
|
||||||
ExFreePool(fip);
|
ExFreePool(fip);
|
||||||
ExFreePool(bip);
|
ExFreePool(bip);
|
||||||
if (SymLinkList != NULL)
|
if (SymLinkList != NULL)
|
||||||
|
@ -255,11 +261,11 @@ IoGetDeviceInterfaces(
|
||||||
ZwClose(InterfaceKey);
|
ZwClose(InterfaceKey);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
SubKeyName.Length = 0;
|
SubKeyName.Length = 0;
|
||||||
SubKeyName.MaximumLength = BaseKeyName.Length + bip->NameLength + sizeof(WCHAR);
|
SubKeyName.MaximumLength = BaseKeyName.Length + bip->NameLength + sizeof(WCHAR);
|
||||||
SubKeyName.Buffer = ExAllocatePool(NonPagedPool, SubKeyName.MaximumLength);
|
SubKeyName.Buffer = ExAllocatePool(NonPagedPool, SubKeyName.MaximumLength);
|
||||||
assert(SubKeyName.Buffer != NULL);
|
ASSERT(SubKeyName.Buffer != NULL);
|
||||||
TempString.Length = TempString.MaximumLength = bip->NameLength;
|
TempString.Length = TempString.MaximumLength = bip->NameLength;
|
||||||
TempString.Buffer = bip->Name;
|
TempString.Buffer = bip->Name;
|
||||||
RtlCopyUnicodeString(&SubKeyName, &BaseKeyName);
|
RtlCopyUnicodeString(&SubKeyName, &BaseKeyName);
|
||||||
|
@ -292,181 +298,263 @@ IoGetDeviceInterfaces(
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ZwEnumerateKey(
|
Status = ZwQueryKey(
|
||||||
SubKey,
|
SubKey,
|
||||||
0,
|
KeyFullInformation,
|
||||||
KeyBasicInformation,
|
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
&Size);
|
&Size);
|
||||||
|
|
||||||
if (Status != STATUS_BUFFER_TOO_SMALL)
|
if (Status != STATUS_BUFFER_TOO_SMALL)
|
||||||
{
|
{
|
||||||
DPRINT("ZwEnumerateKey() Failed. (0x%X)\n", Status);
|
DPRINT("ZwQueryKey() Failed. (0x%X)\n", Status);
|
||||||
ExFreePool(fip);
|
ExFreePool(fip);
|
||||||
if (SymLinkList != NULL)
|
|
||||||
ExFreePool(SymLinkList);
|
|
||||||
RtlFreeUnicodeString(&SubKeyName);
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
RtlFreeUnicodeString(&BaseKeyName);
|
||||||
|
RtlFreeUnicodeString(&SubKeyName);
|
||||||
ZwClose(SubKey);
|
ZwClose(SubKey);
|
||||||
ZwClose(InterfaceKey);
|
ZwClose(InterfaceKey);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
bip = (PKEY_BASIC_INFORMATION)ExAllocatePool(NonPagedPool, Size);
|
bfip = (PKEY_FULL_INFORMATION)ExAllocatePool(NonPagedPool, Size);
|
||||||
assert(bip != NULL);
|
ASSERT(bfip != NULL);
|
||||||
|
|
||||||
Status = ZwEnumerateKey(
|
Status = ZwQueryKey(
|
||||||
SubKey,
|
SubKey,
|
||||||
0,
|
KeyFullInformation,
|
||||||
KeyBasicInformation,
|
bfip,
|
||||||
bip,
|
|
||||||
Size,
|
Size,
|
||||||
&Size);
|
&Size);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("ZwEnumerateKey() Failed. (0x%X)\n", Status);
|
DPRINT("ZwQueryKey() Failed. (0x%X)\n", Status);
|
||||||
ExFreePool(fip);
|
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);
|
||||||
|
RtlFreeUnicodeString(&SubKeyName);
|
||||||
|
RtlFreeUnicodeString(&BaseKeyName);
|
||||||
|
ZwClose(SubKey);
|
||||||
|
ZwClose(InterfaceKey);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
bip = (PKEY_BASIC_INFORMATION)ExAllocatePool(NonPagedPool, Size);
|
||||||
|
ASSERT(bip != NULL);
|
||||||
|
|
||||||
|
Status = ZwEnumerateKey(
|
||||||
|
SubKey,
|
||||||
|
j,
|
||||||
|
KeyBasicInformation,
|
||||||
|
bip,
|
||||||
|
Size,
|
||||||
|
&Size);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwEnumerateKey() Failed.(0x%X)\n", Status);
|
||||||
|
ExFreePool(fip);
|
||||||
|
ExFreePool(bfip);
|
||||||
|
ExFreePool(bip);
|
||||||
|
if (SymLinkList != NULL)
|
||||||
|
ExFreePool(SymLinkList);
|
||||||
|
RtlFreeUnicodeString(&SubKeyName);
|
||||||
|
RtlFreeUnicodeString(&BaseKeyName);
|
||||||
|
ZwClose(SubKey);
|
||||||
|
ZwClose(InterfaceKey);
|
||||||
|
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);
|
||||||
|
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);
|
ExFreePool(bip);
|
||||||
if (SymLinkList != NULL)
|
|
||||||
ExFreePool(SymLinkList);
|
|
||||||
RtlFreeUnicodeString(&SubKeyName);
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
|
||||||
ZwClose(SubKey);
|
|
||||||
ZwClose(InterfaceKey);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
SymbolicLinkKeyName.Length = 0;
|
InitializeObjectAttributes(
|
||||||
SymbolicLinkKeyName.MaximumLength = SubKeyName.Length + bip->NameLength + sizeof(WCHAR);
|
&ObjectAttributes,
|
||||||
SymbolicLinkKeyName.Buffer = ExAllocatePool(NonPagedPool, SymbolicLinkKeyName.MaximumLength);
|
&SymbolicLinkKeyName,
|
||||||
assert(SymbolicLinkKeyName.Buffer != NULL);
|
OBJ_CASE_INSENSITIVE,
|
||||||
TempString.Length = TempString.MaximumLength = bip->NameLength;
|
NULL,
|
||||||
TempString.Buffer = bip->Name;
|
NULL);
|
||||||
RtlCopyUnicodeString(&SymbolicLinkKeyName, &SubKeyName);
|
|
||||||
RtlAppendUnicodeToString(&SymbolicLinkKeyName, L"\\");
|
Status = ZwOpenKey(
|
||||||
RtlAppendUnicodeStringToString(&SymbolicLinkKeyName, &TempString);
|
&SymbolicLinkKey,
|
||||||
|
KEY_READ,
|
||||||
|
&ObjectAttributes);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwOpenKey() Failed. (0x%X)\n", Status);
|
||||||
|
ExFreePool(fip);
|
||||||
|
ExFreePool(bfip);
|
||||||
|
if (SymLinkList != NULL)
|
||||||
|
ExFreePool(SymLinkList);
|
||||||
|
RtlFreeUnicodeString(&SymbolicLinkKeyName);
|
||||||
|
RtlFreeUnicodeString(&SubKeyName);
|
||||||
|
RtlFreeUnicodeString(&BaseKeyName);
|
||||||
|
ZwClose(SubKey);
|
||||||
|
ZwClose(InterfaceKey);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = ZwQueryValueKey(
|
||||||
|
SymbolicLinkKey,
|
||||||
|
&SymbolicLink,
|
||||||
|
KeyValuePartialInformation,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
&Size);
|
||||||
|
|
||||||
|
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||||
|
continue;
|
||||||
|
|
||||||
ExFreePool(bip);
|
if (Status != STATUS_BUFFER_TOO_SMALL)
|
||||||
|
{
|
||||||
|
DPRINT("ZwQueryValueKey() Failed.(0x%X)\n", Status);
|
||||||
|
ExFreePool(fip);
|
||||||
|
ExFreePool(bfip);
|
||||||
|
if (SymLinkList != NULL)
|
||||||
|
ExFreePool(SymLinkList);
|
||||||
|
RtlFreeUnicodeString(&SymbolicLinkKeyName);
|
||||||
|
RtlFreeUnicodeString(&SubKeyName);
|
||||||
|
RtlFreeUnicodeString(&BaseKeyName);
|
||||||
|
ZwClose(SymbolicLinkKey);
|
||||||
|
ZwClose(SubKey);
|
||||||
|
ZwClose(InterfaceKey);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
InitializeObjectAttributes(
|
vpip = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePool(NonPagedPool, Size);
|
||||||
&ObjectAttributes,
|
ASSERT(vpip != NULL);
|
||||||
&SymbolicLinkKeyName,
|
|
||||||
OBJ_CASE_INSENSITIVE,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
Status = ZwOpenKey(
|
Status = ZwQueryValueKey(
|
||||||
&SymbolicLinkKey,
|
SymbolicLinkKey,
|
||||||
KEY_READ,
|
&SymbolicLink,
|
||||||
&ObjectAttributes);
|
KeyValuePartialInformation,
|
||||||
|
vpip,
|
||||||
|
Size,
|
||||||
|
&Size);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwQueryValueKey() Failed.(0x%X)\n", Status);
|
||||||
|
ExFreePool(fip);
|
||||||
|
ExFreePool(bfip);
|
||||||
|
ExFreePool(vpip);
|
||||||
|
if (SymLinkList != NULL)
|
||||||
|
ExFreePool(SymLinkList);
|
||||||
|
RtlFreeUnicodeString(&SymbolicLinkKeyName);
|
||||||
|
RtlFreeUnicodeString(&SubKeyName);
|
||||||
|
RtlFreeUnicodeString(&BaseKeyName);
|
||||||
|
ZwClose(SymbolicLinkKey);
|
||||||
|
ZwClose(SubKey);
|
||||||
|
ZwClose(InterfaceKey);
|
||||||
|
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);
|
||||||
|
RtlCopyMemory(SymLinkList, vpip->Data, vpip->DataLength);
|
||||||
|
SymLinkList[vpip->DataLength / sizeof(WCHAR)] = 0;
|
||||||
|
SymLinkList[1] = '?';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PWCHAR OldSymLinkList;
|
||||||
|
ULONG OldSymLinkListSize;
|
||||||
|
PWCHAR SymLinkListPtr;
|
||||||
|
|
||||||
|
OldSymLinkList = SymLinkList;
|
||||||
|
OldSymLinkListSize = SymLinkListSize;
|
||||||
|
SymLinkListSize += vpip->DataLength;
|
||||||
|
SymLinkList = ExAllocatePool(NonPagedPool, SymLinkListSize + sizeof(WCHAR));
|
||||||
|
ASSERT(SymLinkList != NULL);
|
||||||
|
RtlCopyMemory(SymLinkList, OldSymLinkList, OldSymLinkListSize);
|
||||||
|
ExFreePool(OldSymLinkList);
|
||||||
|
SymLinkListPtr = SymLinkList + (OldSymLinkListSize / sizeof(WCHAR));
|
||||||
|
RtlCopyMemory(SymLinkListPtr, vpip->Data, vpip->DataLength);
|
||||||
|
SymLinkListPtr[vpip->DataLength / sizeof(WCHAR)] = 0;
|
||||||
|
SymLinkListPtr[1] = '?';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("ZwOpenKey() Failed. (0x%X)\n", Status);
|
|
||||||
ExFreePool(fip);
|
|
||||||
if (SymLinkList != NULL)
|
|
||||||
ExFreePool(SymLinkList);
|
|
||||||
RtlFreeUnicodeString(&SymbolicLinkKeyName);
|
RtlFreeUnicodeString(&SymbolicLinkKeyName);
|
||||||
RtlFreeUnicodeString(&SubKeyName);
|
RtlFreeUnicodeString(&ControlKeyName);
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
|
||||||
ZwClose(SubKey);
|
|
||||||
ZwClose(InterfaceKey);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = ZwQueryValueKey(
|
|
||||||
SymbolicLinkKey,
|
|
||||||
&SymbolicLink,
|
|
||||||
KeyValuePartialInformation,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
&Size);
|
|
||||||
|
|
||||||
if (Status != STATUS_BUFFER_TOO_SMALL)
|
|
||||||
{
|
|
||||||
DPRINT("ZwQueryValueKey() Failed. (0x%X)\n", Status);
|
|
||||||
ExFreePool(fip);
|
|
||||||
if (SymLinkList != NULL)
|
|
||||||
ExFreePool(SymLinkList);
|
|
||||||
RtlFreeUnicodeString(&SymbolicLinkKeyName);
|
|
||||||
RtlFreeUnicodeString(&SubKeyName);
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
|
||||||
ZwClose(SymbolicLinkKey);
|
ZwClose(SymbolicLinkKey);
|
||||||
ZwClose(SubKey);
|
|
||||||
ZwClose(InterfaceKey);
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vpip = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePool(NonPagedPool, Size);
|
|
||||||
assert(vpip != NULL);
|
|
||||||
|
|
||||||
Status = ZwQueryValueKey(
|
|
||||||
SymbolicLinkKey,
|
|
||||||
&SymbolicLink,
|
|
||||||
KeyValuePartialInformation,
|
|
||||||
vpip,
|
|
||||||
Size,
|
|
||||||
&Size);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
ExFreePool(fip);
|
|
||||||
ExFreePool(vpip);
|
|
||||||
if (SymLinkList != NULL)
|
|
||||||
ExFreePool(SymLinkList);
|
|
||||||
RtlFreeUnicodeString(&SymbolicLinkKeyName);
|
|
||||||
RtlFreeUnicodeString(&SubKeyName);
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
|
||||||
ZwClose(SymbolicLinkKey);
|
|
||||||
ZwClose(SubKey);
|
|
||||||
ZwClose(InterfaceKey);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Put the name in the string here */
|
|
||||||
if (SymLinkList == NULL)
|
|
||||||
{
|
|
||||||
SymLinkListSize = vpip->DataLength;
|
|
||||||
SymLinkList = ExAllocatePool(NonPagedPool, SymLinkListSize + sizeof(WCHAR));
|
|
||||||
assert(SymLinkList != NULL);
|
|
||||||
RtlCopyMemory(SymLinkList, vpip->Data, vpip->DataLength);
|
|
||||||
SymLinkList[vpip->DataLength / sizeof(WCHAR)] = 0;
|
|
||||||
SymLinkList[1] = '?';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PWCHAR OldSymLinkList;
|
|
||||||
ULONG OldSymLinkListSize;
|
|
||||||
PWCHAR SymLinkListPtr;
|
|
||||||
|
|
||||||
OldSymLinkList = SymLinkList;
|
|
||||||
OldSymLinkListSize = SymLinkListSize;
|
|
||||||
SymLinkListSize += vpip->DataLength;
|
|
||||||
SymLinkList = ExAllocatePool(NonPagedPool, SymLinkListSize + sizeof(WCHAR));
|
|
||||||
assert(SymLinkList != NULL);
|
|
||||||
RtlCopyMemory(SymLinkList, OldSymLinkList, OldSymLinkListSize);
|
|
||||||
ExFreePool(OldSymLinkList);
|
|
||||||
SymLinkListPtr = SymLinkList + (OldSymLinkListSize / sizeof(WCHAR));
|
|
||||||
RtlCopyMemory(SymLinkListPtr, vpip->Data, vpip->DataLength);
|
|
||||||
SymLinkListPtr[vpip->DataLength / sizeof(WCHAR)] = 0;
|
|
||||||
SymLinkListPtr[1] = '?';
|
|
||||||
}
|
|
||||||
|
|
||||||
RtlFreeUnicodeString(&SymbolicLinkKeyName);
|
|
||||||
RtlFreeUnicodeString(&SubKeyName);
|
|
||||||
ZwClose(SymbolicLinkKey);
|
|
||||||
ZwClose(SubKey);
|
|
||||||
ExFreePool(vpip);
|
ExFreePool(vpip);
|
||||||
|
RtlFreeUnicodeString(&SubKeyName);
|
||||||
|
ZwClose(SubKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SymLinkList != NULL)
|
if (SymLinkList != NULL)
|
||||||
|
{
|
||||||
SymLinkList[SymLinkListSize / sizeof(WCHAR)] = 0;
|
SymLinkList[SymLinkListSize / sizeof(WCHAR)] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SymLinkList = ExAllocatePool(NonPagedPool, 2 * sizeof(WCHAR));
|
||||||
|
SymLinkList[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
*SymbolicLinkList = SymLinkList;
|
*SymbolicLinkList = SymLinkList;
|
||||||
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
RtlFreeUnicodeString(&BaseKeyName);
|
||||||
ZwClose(InterfaceKey);
|
ZwClose(InterfaceKey);
|
||||||
|
ExFreePool(bfip);
|
||||||
ExFreePool(fip);
|
ExFreePool(fip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue