+BOOLEAN
+NTAPI
+CmpLinkKeyToHive(
+ _In_z_ PWSTR LinkKeyName,
+ _In_z_ PWSTR TargetKeyName)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING LinkKeyName_U;
+ HANDLE TargetKeyHandle;
+ ULONG Disposition;
+ NTSTATUS Status;
+ PAGED_CODE();
+
+ /* Initialize the object attributes */
+ RtlInitUnicodeString(&LinkKeyName_U, LinkKeyName);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &LinkKeyName_U,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+
+ /* Create the link key */
+ Status = ZwCreateKey(&TargetKeyHandle,
+ KEY_CREATE_LINK,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK,
+ &Disposition);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CM: CmpLinkKeyToHive: couldn't create %S Status = 0x%lx\n",
+ LinkKeyName, Status);
+ return FALSE;
+ }
+
+ /* Check if the new key was actually created */
+ if (Disposition != REG_CREATED_NEW_KEY)
+ {
+ DPRINT1("CM: CmpLinkKeyToHive: %S already exists!\n", LinkKeyName);
+ ZwClose(TargetKeyHandle);
+ return FALSE;
+ }
+
+ /* Set the target key name as link target */
+ Status = ZwSetValueKey(TargetKeyHandle,
+ &CmSymbolicLinkValueName,
+ 0,
+ REG_LINK,
+ TargetKeyName,
+ wcslen(TargetKeyName) * sizeof(WCHAR));
+
+ /* Close the link key handle */
+ ObCloseHandle(TargetKeyHandle, KernelMode);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CM: CmpLinkKeyToHive: couldn't create symbolic link for %S\n",
+ TargetKeyName);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+