static PWCHAR BaseKeyString = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\DeviceClasses\\";
+static
+NTSTATUS
+OpenRegistryHandlesFromSymbolicLink(IN PUNICODE_STRING SymbolicLinkName,
+ IN ACCESS_MASK DesiredAccess,
+ IN OPTIONAL PHANDLE GuidKey,
+ IN OPTIONAL PHANDLE DeviceKey,
+ IN OPTIONAL PHANDLE InstanceKey)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ WCHAR PathBuffer[MAX_PATH];
+ UNICODE_STRING BaseKeyU;
+ UNICODE_STRING GuidString, SubKeyName, ReferenceString;
+ PWCHAR StartPosition, EndPosition;
+ HANDLE ClassesKey;
+ PHANDLE GuidKeyRealP, DeviceKeyRealP, InstanceKeyRealP;
+ HANDLE GuidKeyReal, DeviceKeyReal, InstanceKeyReal;
+ NTSTATUS Status;
+
+ SubKeyName.Buffer = NULL;
+
+ if (GuidKey != NULL)
+ GuidKeyRealP = GuidKey;
+ else
+ GuidKeyRealP = &GuidKeyReal;
+
+ if (DeviceKey != NULL)
+ DeviceKeyRealP = DeviceKey;
+ else
+ DeviceKeyRealP = &DeviceKeyReal;
+
+ if (InstanceKey != NULL)
+ InstanceKeyRealP = InstanceKey;
+ else
+ InstanceKeyRealP = &InstanceKeyReal;
+
+ *GuidKeyRealP = INVALID_HANDLE_VALUE;
+ *DeviceKeyRealP = INVALID_HANDLE_VALUE;
+ *InstanceKeyRealP = INVALID_HANDLE_VALUE;
+
+ BaseKeyU.Buffer = PathBuffer;
+ BaseKeyU.Length = 0;
+ BaseKeyU.MaximumLength = MAX_PATH * sizeof(WCHAR);
+
+ RtlAppendUnicodeToString(&BaseKeyU, BaseKeyString);
+
+ /* Open the DeviceClasses key */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &BaseKeyU,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+ Status = ZwOpenKey(&ClassesKey,
+ DesiredAccess | KEY_ENUMERATE_SUB_KEYS,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to open %wZ\n", &BaseKeyU);
+ goto cleanup;
+ }
+
+ StartPosition = wcschr(SymbolicLinkName->Buffer, L'{');
+ EndPosition = wcschr(SymbolicLinkName->Buffer, L'}');
+ if (!StartPosition || !EndPosition || StartPosition > EndPosition)
+ {
+ DPRINT1("Bad symbolic link: %wZ\n", SymbolicLinkName);
+ return STATUS_INVALID_PARAMETER_1;
+ }
+ GuidString.Buffer = StartPosition;
+ GuidString.MaximumLength = GuidString.Length = (USHORT)((ULONG_PTR)(EndPosition + 1) - (ULONG_PTR)StartPosition);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &GuidString,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ ClassesKey,
+ NULL);
+ Status = ZwOpenKey(GuidKeyRealP,
+ DesiredAccess | KEY_ENUMERATE_SUB_KEYS,
+ &ObjectAttributes);
+ ZwClose(ClassesKey);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to open %wZ%wZ (%x)\n", &BaseKeyU, &GuidString, Status);
+ goto cleanup;
+ }
+
+ SubKeyName.MaximumLength = SymbolicLinkName->Length + sizeof(WCHAR);
+ SubKeyName.Length = 0;
+ SubKeyName.Buffer = ExAllocatePool(PagedPool, SubKeyName.MaximumLength);
+ if (!SubKeyName.Buffer)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto cleanup;
+ }
+
+ RtlAppendUnicodeStringToString(&SubKeyName,
+ SymbolicLinkName);
+
+ SubKeyName.Buffer[SubKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+
+ SubKeyName.Buffer[0] = L'#';
+ SubKeyName.Buffer[1] = L'#';
+ SubKeyName.Buffer[2] = L'?';
+ SubKeyName.Buffer[3] = L'#';
+
+ ReferenceString.Buffer = wcsrchr(SubKeyName.Buffer, '\\');
+ if (ReferenceString.Buffer != NULL)
+ {
+ ReferenceString.Buffer[0] = L'#';
+
+ SubKeyName.Length = (USHORT)((ULONG_PTR)(ReferenceString.Buffer) - (ULONG_PTR)SubKeyName.Buffer);
+ ReferenceString.Length = SymbolicLinkName->Length - SubKeyName.Length;
+ }
+ else
+ {
+ RtlInitUnicodeString(&ReferenceString, L"#");
+ }
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &SubKeyName,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ *GuidKeyRealP,
+ NULL);
+ Status = ZwOpenKey(DeviceKeyRealP,
+ DesiredAccess | KEY_ENUMERATE_SUB_KEYS,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to open %wZ%wZ\\%wZ\n", &BaseKeyU, &GuidString, &SubKeyName);
+ goto cleanup;
+ }
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &ReferenceString,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ *DeviceKeyRealP,
+ NULL);
+ Status = ZwOpenKey(InstanceKeyRealP,
+ DesiredAccess,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to open %wZ%wZ\\%wZ%\\%wZ (%x)\n", &BaseKeyU, &GuidString, &SubKeyName, &ReferenceString, Status);
+ goto cleanup;
+ }
+
+ Status = STATUS_SUCCESS;
+
+cleanup:
+ if (SubKeyName.Buffer != NULL)
+ ExFreePool(SubKeyName.Buffer);
+
+ if (NT_SUCCESS(Status))
+ {
+ if (!GuidKey)
+ ZwClose(*GuidKeyRealP);
+
+ if (!DeviceKey)
+ ZwClose(*DeviceKeyRealP);
+
+ if (!InstanceKey)
+ ZwClose(*InstanceKeyRealP);
+ }
+ else
+ {
+ if (*GuidKeyRealP != INVALID_HANDLE_VALUE)
+ ZwClose(*GuidKeyRealP);
+
+ if (*DeviceKeyRealP != INVALID_HANDLE_VALUE)
+ ZwClose(*DeviceKeyRealP);
+
+ if (*InstanceKeyRealP != INVALID_HANDLE_VALUE)
+ ZwClose(*InstanceKeyRealP);
+ }
+
+ return Status;
+}
/*++
* @name IoOpenDeviceInterfaceRegistryKey
* @unimplemented
IN ACCESS_MASK DesiredAccess,
OUT PHANDLE DeviceInterfaceKey)
{
- WCHAR StrBuff[MAX_PATH], PathBuff[MAX_PATH];
- PWCHAR Guid;
- UNICODE_STRING EnumU = RTL_CONSTANT_STRING(ENUM_ROOT L"\\");
- 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;
- 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);
-
- Guid = wcsstr(StrBuff, L"{");
- if (!Guid)
- return STATUS_OBJECT_NAME_NOT_FOUND;
-
- KeyPath.Buffer = PathBuff;
- KeyPath.Length = 0;
- KeyPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
-
- RtlAppendUnicodeToString(&KeyPath, BaseKeyString);
- RtlAppendUnicodeToString(&KeyPath, Guid);
-
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyPath,
- OBJ_CASE_INSENSITIVE,
- 0,
- NULL);
-
- Status = ZwOpenKey(&GuidKey, KEY_CREATE_SUB_KEY, &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- return Status;
-
- while (TRUE)
- {
- Status = ZwEnumerateKey(GuidKey,
- Index,
- KeyBasicInformation,
- NULL,
- 0,
- &RequiredLength);
- if (Status == STATUS_NO_MORE_ENTRIES)
- break;
- else if (Status == STATUS_BUFFER_TOO_SMALL)
- {
- KeyInformationLength = RequiredLength;
- KeyInformation = ExAllocatePool(PagedPool, KeyInformationLength);
- if (!KeyInformation)
- {
- ZwClose(GuidKey);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- Status = ZwEnumerateKey(GuidKey,
- Index,
- KeyBasicInformation,
- KeyInformation,
- KeyInformationLength,
- &RequiredLength);
- }
- else
- {
- ZwClose(GuidKey);
- return STATUS_OBJECT_PATH_NOT_FOUND;
- }
- Index++;
-
- if (!NT_SUCCESS(Status))
- {
- ZwClose(GuidKey);
- return Status;
- }
-
- KeyName.Length = KeyName.MaximumLength = KeyInformation->NameLength;
- KeyName.Buffer = KeyInformation->Name;
-
- if (!RtlEqualUnicodeString(&KeyName, &MatchableGuid, TRUE))
- 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,
- &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);
- return Status;
- }
-
- return STATUS_OBJECT_PATH_NOT_FOUND;
+ HANDLE InstanceKey, DeviceParametersKey;
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING DeviceParametersU = RTL_CONSTANT_STRING(L"Device Parameters");
+
+ Status = OpenRegistryHandlesFromSymbolicLink(SymbolicLinkName,
+ KEY_CREATE_SUB_KEY,
+ NULL,
+ NULL,
+ &InstanceKey);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &DeviceParametersU,
+ OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
+ InstanceKey,
+ NULL);
+ Status = ZwCreateKey(&DeviceParametersKey,
+ DesiredAccess,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ NULL);
+ ZwClose(InstanceKey);
+
+ if (NT_SUCCESS(Status))
+ *DeviceInterfaceKey = DeviceParametersKey;
+
+ return Status;
}
/*++
}
KeyName.Length = 0;
- KeyName.MaximumLength = LocalMachine.Length + (wcslen(REGSTR_PATH_DEVICE_CLASSES) + 1) * sizeof(WCHAR) + GuidString.Length;
+ KeyName.MaximumLength = LocalMachine.Length + ((USHORT)wcslen(REGSTR_PATH_DEVICE_CLASSES) + 1) * sizeof(WCHAR) + GuidString.Length;
KeyName.Buffer = ExAllocatePool(PagedPool, KeyName.MaximumLength);
if (!KeyName.Buffer)
{
PKEY_BASIC_INFORMATION DeviceBi = NULL;
PKEY_BASIC_INFORMATION ReferenceBi = NULL;
PKEY_VALUE_PARTIAL_INFORMATION bip = NULL;
+ PKEY_VALUE_PARTIAL_INFORMATION PartialInfo;
UNICODE_STRING KeyName;
OBJECT_ATTRIBUTES ObjectAttributes;
BOOLEAN FoundRightPDO = FALSE;
- ULONG i = 0, j, Size;
+ ULONG i = 0, j, Size, NeededLength, ActualLength, LinkedValue;
UNICODE_STRING ReturnBuffer = { 0, 0, NULL };
NTSTATUS Status;
/* We have to check if the interface is enabled, by
* reading the Linked value in the Control subkey
*/
-#if 0
InitializeObjectAttributes(
&ObjectAttributes,
&Control,
}
else if (!NT_SUCCESS(Status))
{
- DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
+ DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status);
+ goto cleanup;
+ }
+
+ RtlInitUnicodeString(&KeyName, L"Linked");
+ Status = ZwQueryValueKey(ControlKey,
+ &KeyName,
+ KeyValuePartialInformation,
+ NULL,
+ 0,
+ &NeededLength);
+ if (Status == STATUS_BUFFER_TOO_SMALL)
+ {
+ ActualLength = NeededLength;
+ PartialInfo = ExAllocatePool(NonPagedPool, ActualLength);
+ if (!PartialInfo)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto cleanup;
+ }
+
+ Status = ZwQueryValueKey(ControlKey,
+ &KeyName,
+ KeyValuePartialInformation,
+ PartialInfo,
+ ActualLength,
+ &NeededLength);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("ZwQueryValueKey #2 failed (%x)\n", Status);
+ ExFreePool(PartialInfo);
+ goto cleanup;
+ }
+
+ if (PartialInfo->Type != REG_DWORD || PartialInfo->DataLength != sizeof(ULONG))
+ {
+ DPRINT1("Bad registry read\n");
+ ExFreePool(PartialInfo);
+ goto cleanup;
+ }
+
+ RtlCopyMemory(&LinkedValue,
+ PartialInfo->Data,
+ PartialInfo->DataLength);
+
+ ExFreePool(PartialInfo);
+ if (LinkedValue == 0)
+ {
+ /* This interface isn't active */
+ goto NextReferenceString;
+ }
+ }
+ else
+ {
+ DPRINT1("ZwQueryValueKey #1 failed (%x)\n", Status);
goto cleanup;
}
-#endif
- /* FIXME: Read the Linked value
- * If it doesn't exist => ERROR
- * If it is not a REG_DWORD or Size != sizeof(ULONG) => ERROR
- * If its value is 0, go to NextReferenceString
- * At the moment, do as if it is active...
- */
- DPRINT1("Checking if device is enabled is not implemented yet!\n");
}
/* Read the SymbolicLink string and add it into SymbolicLinkList */
}
KeyName.Length = KeyName.MaximumLength = (USHORT)bip->DataLength - 4 * sizeof(WCHAR);
KeyName.Buffer = &((PWSTR)bip->Data)[4];
- if (KeyName.Length && KeyName.Buffer[KeyName.Length / sizeof(WCHAR)] == UNICODE_NULL)
- {
- /* Remove trailing NULL */
- KeyName.Length -= sizeof(WCHAR);
- }
/* Add new symbolic link to symbolic link list */
if (ReturnBuffer.Length + KeyName.Length + sizeof(WCHAR) > ReturnBuffer.MaximumLength)
{
PWSTR NewBuffer;
- ReturnBuffer.MaximumLength = max(ReturnBuffer.MaximumLength * 2, ReturnBuffer.Length + KeyName.Length + 2 * sizeof(WCHAR));
+ ReturnBuffer.MaximumLength = (USHORT)max(ReturnBuffer.MaximumLength * 2,
+ ReturnBuffer.Length + KeyName.Length + 2 * sizeof(WCHAR));
NewBuffer = ExAllocatePool(PagedPool, ReturnBuffer.MaximumLength);
if (!NewBuffer)
{
goto cleanup;
}
/* RtlAppendUnicodeStringToString added a NULL at the end of the
- * destination string, but didn't increase the Length field.
- * Do it for it.
- */
+ * destination string, but didn't increase the Length field.
+ * Do it for it.
+ */
ReturnBuffer.Length += sizeof(WCHAR);
NextReferenceString:
ExFreePool(ReferenceBi);
ReferenceBi = NULL;
- ExFreePool(bip);
+ if (bip)
+ ExFreePool(bip);
bip = NULL;
if (ReferenceKey != INVALID_HANDLE_VALUE)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto cleanup;
}
- RtlCopyMemory(NewBuffer, ReturnBuffer.Buffer, ReturnBuffer.Length);
- ExFreePool(ReturnBuffer.Buffer);
+ if (ReturnBuffer.Buffer)
+ {
+ RtlCopyMemory(NewBuffer, ReturnBuffer.Buffer, ReturnBuffer.Length);
+ ExFreePool(ReturnBuffer.Buffer);
+ }
ReturnBuffer.Buffer = NewBuffer;
}
ReturnBuffer.Buffer[ReturnBuffer.Length / sizeof(WCHAR)] = UNICODE_NULL;
ULONG StartIndex;
OBJECT_ATTRIBUTES ObjectAttributes;
ULONG i;
- NTSTATUS Status;
+ NTSTATUS Status, SymLinkStatus;
PEXTENDED_DEVOBJ_EXTENSION DeviceObjectExtension;
ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
/* Create base key name for this interface: HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses\{GUID} */
ASSERT(((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode);
InstancePath = &((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode->InstancePath;
- BaseKeyName.Length = wcslen(BaseKeyString) * sizeof(WCHAR);
+ BaseKeyName.Length = (USHORT)wcslen(BaseKeyString) * sizeof(WCHAR);
BaseKeyName.MaximumLength = BaseKeyName.Length
+ GuidString.Length;
BaseKeyName.Buffer = ExAllocatePool(
/* Create symbolic link */
DPRINT("IoRegisterDeviceInterface(): creating symbolic link %wZ -> %wZ\n", SymbolicLinkName, &PdoNameInfo->Name);
- Status = IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name);
- if (!NT_SUCCESS(Status) && ReferenceString == NULL)
+ SymLinkStatus = IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name);
+
+ /* If the symbolic link already exists, return an informational success status */
+ if (SymLinkStatus == STATUS_OBJECT_NAME_COLLISION)
+ {
+ /* HACK: Delete the existing symbolic link and update it to the new PDO name */
+ IoDeleteSymbolicLink(SymbolicLinkName);
+ IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name);
+ SymLinkStatus = STATUS_OBJECT_NAME_EXISTS;
+ }
+
+ if (!NT_SUCCESS(SymLinkStatus))
{
- DPRINT1("IoCreateSymbolicLink() failed with status 0x%08lx\n", Status);
+ DPRINT1("IoCreateSymbolicLink() failed with status 0x%08lx\n", SymLinkStatus);
ZwClose(SubKey);
ZwClose(InterfaceKey);
ZwClose(ClassKey);
ExFreePool(InterfaceKeyName.Buffer);
ExFreePool(BaseKeyName.Buffer);
ExFreePool(SymbolicLinkName->Buffer);
- return Status;
+ return SymLinkStatus;
}
if (ReferenceString && ReferenceString->Length)
ExFreePool(InterfaceKeyName.Buffer);
ExFreePool(BaseKeyName.Buffer);
- return Status;
+ return NT_SUCCESS(Status) ? SymLinkStatus : Status;
}
/*++
PWCHAR EndPosition;
NTSTATUS Status;
LPCGUID EventGuid;
-
+ HANDLE InstanceHandle, ControlHandle;
+ UNICODE_STRING KeyName;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ ULONG LinkedValue;
+ GUID DeviceGuid;
if (SymbolicLinkName == NULL)
return STATUS_INVALID_PARAMETER_1;
SymLink.Buffer = SymbolicLinkName->Buffer;
SymLink.MaximumLength = SymLink.Length = (USHORT)((ULONG_PTR)(EndPosition + 1) - (ULONG_PTR)SymLink.Buffer);
DPRINT("IoSetDeviceInterfaceState('%wZ', %d)\n", SymbolicLinkName, Enable);
+
+ Status = OpenRegistryHandlesFromSymbolicLink(SymbolicLinkName,
+ KEY_CREATE_SUB_KEY,
+ NULL,
+ NULL,
+ &InstanceHandle);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ RtlInitUnicodeString(&KeyName, L"Control");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ InstanceHandle,
+ NULL);
+ Status = ZwCreateKey(&ControlHandle,
+ KEY_SET_VALUE,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_VOLATILE,
+ NULL);
+ ZwClose(InstanceHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create the Control subkey\n");
+ return Status;
+ }
+
+ LinkedValue = (Enable ? 1 : 0);
+
+ RtlInitUnicodeString(&KeyName, L"Linked");
+ Status = ZwSetValueKey(ControlHandle,
+ &KeyName,
+ 0,
+ REG_DWORD,
+ &LinkedValue,
+ sizeof(ULONG));
+ ZwClose(ControlHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to write the Linked value\n");
+ return Status;
+ }
+
/* Get pointer to the PDO */
Status = IoGetDeviceObjectPointer(
&SymLink,
return Status;
}
+ Status = RtlGUIDFromString(&GuidString, &DeviceGuid);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlGUIDFromString() failed with status 0x%08lx\n", Status);
+ return Status;
+ }
+
EventGuid = Enable ? &GUID_DEVICE_INTERFACE_ARRIVAL : &GUID_DEVICE_INTERFACE_REMOVAL;
IopNotifyPlugPlayNotification(
PhysicalDeviceObject,
EventCategoryDeviceInterfaceChange,
EventGuid,
- &GuidString,
+ &DeviceGuid,
(PVOID)SymbolicLinkName);
ObDereferenceObject(FileObject);