[USB]
[reactos.git] / reactos / ntoskrnl / io / iomgr / deviface.c
index 912a0ec..9b40aab 100644 (file)
@@ -887,7 +887,7 @@ IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject,
     ULONG StartIndex;
     OBJECT_ATTRIBUTES ObjectAttributes;
     ULONG i;
-    NTSTATUS Status;
+    NTSTATUS Status, SymLinkStatus;
     PEXTENDED_DEVOBJ_EXTENSION DeviceObjectExtension;
 
     ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
@@ -1137,25 +1137,24 @@ IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject,
     }
     RtlAppendUnicodeToString(SymbolicLinkName, L"#");
     RtlAppendUnicodeStringToString(SymbolicLinkName, &GuidString);
+    SymbolicLinkName->Buffer[SymbolicLinkName->Length/sizeof(WCHAR)] = L'\0';
 
-    if (ReferenceString && ReferenceString->Length)
+    /* Create symbolic link */
+    DPRINT("IoRegisterDeviceInterface(): creating symbolic link %wZ -> %wZ\n", SymbolicLinkName, &PdoNameInfo->Name);
+    SymLinkStatus = IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name);
+
+    /* If the symbolic link already exists, return an informational success status */
+    if (SymLinkStatus == STATUS_OBJECT_NAME_COLLISION)
     {
-        RtlAppendUnicodeToString(SymbolicLinkName, L"\\");
-        RtlAppendUnicodeStringToString(SymbolicLinkName, ReferenceString);
+        /* 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;
     }
-    SymbolicLinkName->Buffer[SymbolicLinkName->Length/sizeof(WCHAR)] = L'\0';
 
-    /* Write symbolic link name in registry */
-    SymbolicLinkName->Buffer[1] = '\\';
-    Status = ZwSetValueKey(SubKey,
-                           &SymbolicLink,
-                           0, /* TileIndex */
-                           REG_SZ,
-                           SymbolicLinkName->Buffer,
-                           SymbolicLinkName->Length);
-    if (!NT_SUCCESS(Status))
+    if (!NT_SUCCESS(SymLinkStatus))
     {
-        DPRINT1("ZwSetValueKey() failed with status 0x%08lx\n", Status);
+        DPRINT1("IoCreateSymbolicLink() failed with status 0x%08lx\n", SymLinkStatus);
         ZwClose(SubKey);
         ZwClose(InterfaceKey);
         ZwClose(ClassKey);
@@ -1163,27 +1162,34 @@ IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject,
         ExFreePool(InterfaceKeyName.Buffer);
         ExFreePool(BaseKeyName.Buffer);
         ExFreePool(SymbolicLinkName->Buffer);
-        return Status;
+        return SymLinkStatus;
     }
-    else
+
+    if (ReferenceString && ReferenceString->Length)
     {
-        SymbolicLinkName->Buffer[1] = '?';
+        RtlAppendUnicodeToString(SymbolicLinkName, L"\\");
+        RtlAppendUnicodeStringToString(SymbolicLinkName, ReferenceString);
     }
+    SymbolicLinkName->Buffer[SymbolicLinkName->Length/sizeof(WCHAR)] = L'\0';
 
-    /* Create symbolic link */
-    DPRINT("IoRegisterDeviceInterface(): creating symbolic link %wZ -> %wZ\n", SymbolicLinkName, &PdoNameInfo->Name);
-    Status = IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name);
-
-    /* If the symbolic link already exists, return an informational success status */
-    if (Status == STATUS_OBJECT_NAME_COLLISION)
-        Status = STATUS_OBJECT_NAME_EXISTS;
-
-    /* Check if it really failed */
+    /* Write symbolic link name in registry */
+    SymbolicLinkName->Buffer[1] = '\\';
+    Status = ZwSetValueKey(
+        SubKey,
+        &SymbolicLink,
+        0, /* TileIndex */
+        REG_SZ,
+        SymbolicLinkName->Buffer,
+        SymbolicLinkName->Length);
     if (!NT_SUCCESS(Status))
     {
-        DPRINT1("IoCreateSymbolicLink() failed with status 0x%08lx\n", Status);
+        DPRINT1("ZwSetValueKey() failed with status 0x%08lx\n", Status);
         ExFreePool(SymbolicLinkName->Buffer);
     }
+    else
+    {
+        SymbolicLinkName->Buffer[1] = '?';
+    }
 
     ZwClose(SubKey);
     ZwClose(InterfaceKey);
@@ -1192,7 +1198,7 @@ IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject,
     ExFreePool(InterfaceKeyName.Buffer);
     ExFreePool(BaseKeyName.Buffer);
 
-    return Status;
+    return NT_SUCCESS(Status) ? SymLinkStatus : Status;
 }
 
 /*++