[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/2] Rework network settings copy code.


  • To: <win-pv-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Owen Smith <owen.smith@xxxxxxxxxx>
  • Date: Thu, 22 Sep 2022 07:58:06 +0100
  • Authentication-results: esa1.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none
  • Cc: Owen Smith <owen.smith@xxxxxxxxxx>
  • Delivery-date: Thu, 22 Sep 2022 06:58:28 +0000
  • Ironport-data: A9a23:8pjTB6kD16/RXQeLA/qo8qHo5gzCJkRdPkR7XQ2eYbSJt1+Wr1Gzt xIaXjqEOPnbNjCjLd9xb4iz9k8G75/Um9MwTgo4/3g8FiMWpZLJC+rCIxarNUt+DCFioGGLT Sk6QoOdRCzhZiaE/n9BCpC48T8mk/ngqoPUUIbsIjp2SRJvVBAvgBdin/9RqoNziJ2yDhjlV ena+qUzA3f4nW8vWo4ow/jb8kk37a6o4GpwUmEWPpingnePzxH5M7pHTU2BByOQapVZGOe8W 9HCwNmRlo8O105wYj8Nuu+TnnwiGtY+DyDX4pZlc/HKbix5jj4zys4G2M80Mi+7vdkrc+dZk 72hvbToIesg0zaldO41C3G0GAkmVUFKFSOuzdFSfqV/wmWfG0YAzcmCA2kyH9dDpMNtAlpg7 N06Lz8AT06no+OplefTpulE3qzPLeHuNYIb/Hph0SvYHbAtRpWrr6fivIECmm1q34YXQKiYN 5FxhTlHNXwsZzVIJVoRTok7nfuornL+bydZuBSeoq9fD237nFUsiuW3bYe9ltqiHO9Pz2qU/ W39wVvoOBc8BcbH1RWm2yf57gPItXyiA99DfFGizdZ1gVvW3nJWBBAIWF+TpfiillX4S99ZM 1YT+Cclse417kPDczXmd0Tm+jje5EdaAocOVb1hgO2Q9kbKywK7XDNaayRCU/I/le0xSjELi Hutnsy8UFSDr4appWKhGqa89G3sYnZJcTRZOUfoXiNevYC9/dhbYgbnC486TfXr1oCd9STYm WjikcQou1kEYSfnPY2f9EuPvT+jr4OhouUdtlSOBTLNAu+UieeYi22UBbvzt6wowH6xFAXpg ZT9s5H2ABoyJZ+MjjeRZ+4GAauk4f2IWBWF3wA0QMl8rGnyoyP6FWy13N2ZDBgBDyr5UWWxP B+7Vf15vfe/w0dGnYcoOtnsWqzGPIDrFMj/V+C8U+eilqNZLVbflByCkGbKgAgBZmBwzvxkU XpaGO7wZUsn5VNPl2XpH7ZMiORxn0jTBwr7HPjG8vhu6pLGDFb9dFvPGALmgjwRhE9cnDjoz g==
  • Ironport-hdrordr: A9a23:n3VTQ6suUAopwdI6AThU5OXc7skDTtV00zEX/kB9WHVpmszxra 6TdZMgpHnJYVcqKQkdcL+7WJVoLUmxyXcx2/h1AV7AZniAhILLFvAA0WKK+VSJcEeSygce79 YFT0EXMqyIMbEQt6fHCWeDfOrIuOP3kpyVuQ==
  • List-id: Developer list for the Windows PV Drivers subproject <win-pv-devel.lists.xenproject.org>

Rather than copying network settings twice (once on save and once on restore),
stash the current network interface guid and network Luid on save and copy
settings from the previous to the new location on restore.
By relying on the current settings, the copy code will always restore the
settings that are current. This will pick up any changes that are made without
requiring a copy from the save.

Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
 src/xenvif/pdo.c      |  93 +++--
 src/xenvif/settings.c | 810 +++++++++++++++++++++++-------------------
 2 files changed, 508 insertions(+), 395 deletions(-)

diff --git a/src/xenvif/pdo.c b/src/xenvif/pdo.c
index b3a4aae..82775b4 100644
--- a/src/xenvif/pdo.c
+++ b/src/xenvif/pdo.c
@@ -1180,6 +1180,45 @@ fail1:
     return status;
 }
 
+static NTSTATUS
+PdoGetInterfaceLuid(
+    IN  PXENVIF_PDO Pdo,
+    IN  HANDLE      Key,
+    OUT PNET_LUID   Luid
+    )
+{
+    ULONG           Value;
+    NTSTATUS        status;
+
+    UNREFERENCED_PARAMETER(Pdo);
+
+    status = RegistryQueryDwordValue(Key,
+                                     "*IfType",
+                                     &Value);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    Luid->Info.IfType = Value;
+
+    status = RegistryQueryDwordValue(Key,
+                                     "NetLuidIndex",
+                                     &Value);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    Luid->Info.NetLuidIndex = Value;
+
+    return STATUS_SUCCESS;
+
+fail2:
+    Error("fail2\n");
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
 static VOID
 PdoUnplugRequest(
     IN  PXENVIF_PDO Pdo,
@@ -1216,7 +1255,6 @@ PdoStartDevice(
     PIO_STACK_LOCATION  StackLocation;
     HANDLE              SoftwareKey;
     HANDLE              HardwareKey;
-    ULONG               HasSettings;
     GUID                Guid;
     NTSTATUS            status;
 
@@ -1307,39 +1345,44 @@ PdoStartDevice(
         goto fail9;
     }
 
-    status = RegistryQueryDwordValue(SoftwareKey,
-                                     "HasSettings",
-                                     &HasSettings);
-    if (!NT_SUCCESS(status))
-        HasSettings = 0;
-
-    if (HasSettings == 0) {
-        //
-        // If there is a stack bound then restore any settings that
-        // may have been saved from an aliasing emulated device.
-        //
-        status = PdoGetInterfaceGuid(Pdo, SoftwareKey, &Guid);
+    //
+    // If there is a stack bound then restore any settings that
+    // may have been saved from an aliasing emulated device.
+    //
+    status = PdoGetInterfaceGuid(Pdo, SoftwareKey, &Guid);
+    if (NT_SUCCESS(status)) {
+        NET_LUID        NetLuid;
+        PWCHAR          Alias;
+        PWCHAR          Description;
+
+        RtlZeroMemory(&NetLuid, sizeof(NET_LUID));
+        Alias = NULL;
+        Description = NULL;
+
+        status = PdoGetInterfaceLuid(Pdo, SoftwareKey, &NetLuid);
         if (NT_SUCCESS(status)) {
             for (Index = 0; Index < Table->NumEntries; Index++) {
                 PMIB_IF_ROW2    Row = &Table->Table[Index];
 
-                if (!IsEqualGUID(&Row->InterfaceGuid, &Guid))
+                Trace("%s: CHECKING %ws (%ws)\n",
+                    __PdoGetName(Pdo),
+                    Row->Alias,
+                    Row->Description);
+
+                if (Row->InterfaceLuid.Value != NetLuid.Value)
                     continue;
 
-                (VOID) SettingsRestore(__PdoGetName(Pdo),
-                                       Row->Alias,
-                                       Row->Description,
-                                       &Row->InterfaceGuid,
-                                       &Row->InterfaceLuid);
+                Alias = Row->Alias;
+                Description = Row->Description;
                 break;
             }
-
-            HasSettings = 1;
-
-            (VOID) RegistryUpdateDwordValue(SoftwareKey,
-                                            "HasSettings",
-                                             HasSettings);
         }
+
+        (VOID) SettingsRestore(__PdoGetName(Pdo),
+                               Alias,
+                               Description,
+                               &Guid,
+                               &NetLuid);
     }
 
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
diff --git a/src/xenvif/settings.c b/src/xenvif/settings.c
index 214248b..7f9a14b 100644
--- a/src/xenvif/settings.c
+++ b/src/xenvif/settings.c
@@ -40,6 +40,12 @@
 
 #define SETTINGS_TAG 'TTES'
 
+#define INTERFACES_PATH(_Name) 
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\" ## #_Name ## 
"\\Parameters\\Interfaces\\"
+
+#define IPV6_PATH 
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Nsi\\{eb004a01-9b1a-11d4-9123-0050047759bc}\\10"
+
+#define IPV4_PATH 
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Nsi\\{eb004a00-9b1a-11d4-9123-0050047759bc}\\10"
+
 static FORCEINLINE PVOID
 __SettingsAllocate(
     IN  ULONG   Length
@@ -56,482 +62,444 @@ __SettingsFree(
     __FreePoolWithTag(Buffer, SETTINGS_TAG);
 }
 
-typedef struct _SETTINGS_INTERFACE_COPY_PARAMETERS {
-    PCHAR   SaveKeyName;
-    HANDLE  DestinationKey;
-} SETTINGS_INTERFACE_COPY_PARAMETERS, *PSETTINGS_INTERFACE_COPY_PARAMETERS;
-
-static NTSTATUS
-SettingsCopyInterfaceValue(
-    IN  PVOID                           Context,
-    IN  HANDLE                          SourceKey,
-    IN  PANSI_STRING                    ValueName,
-    IN  ULONG                           Type
+static FORCEINLINE NTSTATUS
+__GuidToString(
+    IN  LPGUID          Guid,
+    OUT PANSI_STRING    Ansi
     )
 {
-    PSETTINGS_INTERFACE_COPY_PARAMETERS Parameters = Context;
-    NTSTATUS                            status;
+    NTSTATUS            status;
+    UNICODE_STRING      Unicode;
 
-    Trace("%s:%Z\n", Parameters->SaveKeyName, ValueName);
+    status = RtlStringFromGUID(Guid, &Unicode);
+    if (!NT_SUCCESS(status))
+        goto fail1;
 
-    switch (Type) {
-    case REG_DWORD: {
-        ULONG   Value;
+    status = RtlUnicodeStringToAnsiString(Ansi, &Unicode, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail2;
 
-        status = RegistryQueryDwordValue(SourceKey,
-                                         ValueName->Buffer,
-                                         &Value);
-        if (NT_SUCCESS(status))
-            (VOID) RegistryUpdateDwordValue(Parameters->DestinationKey,
-                                            ValueName->Buffer,
-                                            Value);
+    RtlFreeUnicodeString(&Unicode);
 
-        break;
-    }
-    case REG_SZ:
-    case REG_MULTI_SZ: {
-        PANSI_STRING    Value;
+    return STATUS_SUCCESS;
 
-        status = RegistryQuerySzValue(SourceKey,
-                                      ValueName->Buffer,
-                                      NULL,
-                                      &Value);
-        if (NT_SUCCESS(status)) {
-            (VOID) RegistryUpdateSzValue(Parameters->DestinationKey,
-                                         ValueName->Buffer,
-                                         Type,
-                                         Value);
-            RegistryFreeSzValue(Value);
-        }
+fail2:
+    Error("fail2\n");
 
-        break;
-    }
-    case REG_BINARY: {
-        PVOID   Value;
-        ULONG   Length;
-
-        status = RegistryQueryBinaryValue(SourceKey,
-                                          ValueName->Buffer,
-                                          &Value,
-                                          &Length);
-        if (NT_SUCCESS(status)) {
-            (VOID) RegistryUpdateBinaryValue(Parameters->DestinationKey,
-                                             ValueName->Buffer,
-                                             Value,
-                                             Length);
-            if (Length != 0)
-                RegistryFreeBinaryValue(Value);
-        }
-
-        break;
-    }
-    default:
-        ASSERT(FALSE);
-    }
+    RtlFreeUnicodeString(&Unicode);
 
-    return STATUS_SUCCESS;
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
 }
 
+typedef struct _SETTINGS_COPY_IP_ADDRESS_PARAMETERS {
+    PCHAR               SrcPrefix;
+    PCHAR               DstPrefix;
+} SETTINGS_COPY_IP_ADDRESS_PARAMETERS, *PSETTINGS_COPY_IP_ADDRESS_PARAMETERS;
+
 static NTSTATUS
-SettingsCopyInterface(
-    IN  HANDLE      SettingsKey,
-    IN  PCHAR       SaveKeyName,
-    IN  PCHAR       InterfacesPath,
-    IN  PCHAR       InterfacePrefix,
-    IN  LPGUID      Guid,
-    IN  BOOLEAN     Save
+SettingsCopyIpAddressesValue(
+    IN  PVOID                               Context,
+    IN  HANDLE                              Key,
+    IN  PANSI_STRING                        ValueName,
+    IN  ULONG                               Type
     )
 {
-    UNICODE_STRING  Unicode;
-    ULONG           Length;
-    PCHAR           InterfaceName;
-    HANDLE          InterfacesKey;
-    PCHAR           KeyName;
-    HANDLE          Key;
-    HANDLE          SaveKey;
-    NTSTATUS        status;
-
-    Trace("====>\n");
-
-    status = RtlStringFromGUID(Guid, &Unicode);
-    if (!NT_SUCCESS(status))
-        goto fail1;
+    PSETTINGS_COPY_IP_ADDRESS_PARAMETERS    Parameters = Context;
+    ULONG                                   Length;
+    PVOID                                   Value;
+    ULONG                                   ValueLength;
+    NTSTATUS                                status;
 
-    Length = (ULONG)(((Unicode.Length / sizeof (WCHAR)) +
-                      1) * sizeof (CHAR));
+    UNREFERENCED_PARAMETER(Type);
 
-    InterfaceName = __SettingsAllocate(Length);
+    Length = (ULONG)strlen(Parameters->SrcPrefix);
 
-    status = STATUS_NO_MEMORY;
-    if (InterfaceName == NULL)
-        goto fail2;
+    if (_strnicmp(ValueName->Buffer,
+                  Parameters->SrcPrefix,
+                  Length) != 0)
+        goto done;
 
-    status = RtlStringCbPrintfA(InterfaceName,
-                                Length,
-                                "%wZ",
-                                &Unicode);
-    ASSERT(NT_SUCCESS(status));
+    Trace("    -> %Z\n", ValueName);
 
-    status = RegistryOpenSubKey(NULL,
-                                InterfacesPath,
-                                KEY_ALL_ACCESS,
-                                &InterfacesKey);
+    status = RegistryQueryBinaryValue(Key,
+                                      ValueName->Buffer,
+                                      &Value,
+                                      &ValueLength);
     if (!NT_SUCCESS(status))
-        goto fail3;
-
-    Length = (ULONG)((strlen(InterfacePrefix) +
-                      strlen(InterfaceName) +
-                      1) * sizeof (CHAR));
-
-    KeyName = __SettingsAllocate(Length);
-
-    status = STATUS_NO_MEMORY;
-    if (KeyName == NULL)
-        goto fail4;
+        goto fail1;
 
-    status = RtlStringCbPrintfA(KeyName,
-                                Length,
-                                "%s%s",
-                                InterfacePrefix,
-                                InterfaceName);
-    ASSERT(NT_SUCCESS(status));
-
-    status = (!Save) ?
-        RegistryCreateSubKey(InterfacesKey,
-                             KeyName,
-                             REG_OPTION_NON_VOLATILE,
-                             &Key) :
-        RegistryOpenSubKey(InterfacesKey,
-                           KeyName,
-                           KEY_READ,
-                           &Key);
+    status = RegistryDeleteValue(Key,
+                                 ValueName->Buffer);
     if (!NT_SUCCESS(status))
-        goto fail5;
+        goto fail2;
 
-    status = (Save) ?
-        RegistryCreateSubKey(SettingsKey,
-                             SaveKeyName,
-                             REG_OPTION_NON_VOLATILE,
-                             &SaveKey) :
-        RegistryOpenSubKey(SettingsKey,
-                           SaveKeyName,
-                           KEY_READ,
-                           &SaveKey);
-    if (!NT_SUCCESS(status))
-        goto fail6;
+    ASSERT(Length < ValueName->Length);
+    memcpy(ValueName->Buffer, Parameters->DstPrefix, Length);
 
-    if (Save) {
-        SETTINGS_INTERFACE_COPY_PARAMETERS  Parameters;
+    Trace("    <- %Z\n", ValueName);
 
-        Parameters.SaveKeyName = SaveKeyName;
-        Parameters.DestinationKey = SaveKey;
+    status = RegistryUpdateBinaryValue(Key,
+                                       ValueName->Buffer,
+                                       Value,
+                                       ValueLength);
+    if (!NT_SUCCESS(status))
+        goto fail3;
 
-        status = RegistryEnumerateValues(Key,
-                                         SettingsCopyInterfaceValue,
-                                         &Parameters);
-    } else { // Restore
-        SETTINGS_INTERFACE_COPY_PARAMETERS  Parameters;
+    if (ValueLength != 0)
+        RegistryFreeBinaryValue(Value);
 
-        Parameters.SaveKeyName = SaveKeyName;
-        Parameters.DestinationKey = Key;
+done:
+    return STATUS_SUCCESS;
 
-        status = RegistryEnumerateValues(SaveKey,
-                                         SettingsCopyInterfaceValue,
-                                         &Parameters);
-    }
+fail3:
+    Error("fail3\n");
 
-    if (!NT_SUCCESS(status))
-        goto fail7;
+fail2:
+    Error("fail2\n");
 
-    RegistryCloseKey(SaveKey);
+    if (ValueLength != 0)
+        RegistryFreeBinaryValue(Value);
 
-    RegistryCloseKey(Key);
+fail1:
+    Error("fail1 (%08x)\n", status);
 
-    __SettingsFree(KeyName);
+    return status;
+}
 
-    RegistryCloseKey(InterfacesKey);
+static NTSTATUS
+SettingsCopyIpAddresses(
+    IN  ULONG                           Version,
+    IN  PNET_LUID                       OldLuid,
+    IN  PNET_LUID                       NewLuid
+    )
+{
+    PCHAR                               Path;
+    CHAR                                SrcPrefix[17];
+    CHAR                                DstPrefix[17];
+    SETTINGS_COPY_IP_ADDRESS_PARAMETERS Parameters;
+    HANDLE                              Key;
+    NTSTATUS                            status;
 
-    __SettingsFree(InterfaceName);
+    Path = Version == 4 ? IPV4_PATH : IPV6_PATH;
 
-    RtlFreeUnicodeString(&Unicode);
+    status = RtlStringCbPrintfA(SrcPrefix,
+                                sizeof(SrcPrefix),
+                                "%16llx",
+                                _byteswap_uint64(OldLuid->Value));
+    if (!NT_SUCCESS(status))
+        goto fail1;
 
-    Trace("<====\n");
+    status = RtlStringCbPrintfA(DstPrefix,
+                                sizeof(DstPrefix),
+                                "%16llx",
+                                _byteswap_uint64(NewLuid->Value));
+    if (!NT_SUCCESS(status))
+        goto fail2;
 
-    return STATUS_SUCCESS;
+    status = RegistryOpenSubKey(NULL,
+                                Path,
+                                KEY_ALL_ACCESS,
+                                &Key);
+    if (!NT_SUCCESS(status))
+        goto fail3;
 
-fail7:
-    Error("fail7\n");
+    Info("IPv%u: %s -> %s\n", Version, SrcPrefix, DstPrefix);
 
-    RegistryCloseKey(SaveKey);
+    Parameters.SrcPrefix = SrcPrefix;
+    Parameters.DstPrefix = DstPrefix;
 
-fail6:
-    Error("fail6\n");
+    status = RegistryEnumerateValues(Key,
+                                     SettingsCopyIpAddressesValue,
+                                     &Parameters);
+    if (!NT_SUCCESS(status))
+        goto fail4;
 
     RegistryCloseKey(Key);
 
-fail5:
-    Error("fail5\n");
-
-    __SettingsFree(KeyName);
+    return STATUS_SUCCESS;
 
 fail4:
     Error("fail4\n");
 
-    RegistryCloseKey(InterfacesKey);
+    RegistryCloseKey(Key);
 
 fail3:
     Error("fail3\n");
 
-    __SettingsFree(InterfaceName);
-
 fail2:
     Error("fail2\n");
 
-    RtlFreeUnicodeString(&Unicode);
-
 fail1:
     Error("fail1 (%08x)\n", status);
 
     return status;
 }
 
-typedef struct _SETTINGS_IP_ADDRESSES_COPY_PARAMETERS {
-    UCHAR   Version;
-    PCHAR   SourceValuePrefix;
-    HANDLE  DestinationKey;
-    PCHAR   DestinationValuePrefix;
-} SETTINGS_IP_ADDRESSES_COPY_PARAMETERS, 
*PSETTINGS_IP_ADDRESSES_COPY_PARAMETERS;
+static NTSTATUS
+SettingsCopyInterfaceValue(
+   IN  PVOID            Context,
+   IN  HANDLE           SourceKey,
+   IN  PANSI_STRING     ValueName,
+   IN  ULONG            Type
+   )
+{
+   HANDLE               DestinationKey = Context;
+   NTSTATUS             status;
+
+   Trace(" - %Z\n", ValueName);
+
+   switch (Type) {
+   case REG_DWORD: {
+       ULONG   Value;
+
+       status = RegistryQueryDwordValue(SourceKey,
+                                        ValueName->Buffer,
+                                        &Value);
+       if (NT_SUCCESS(status))
+           (VOID) RegistryUpdateDwordValue(DestinationKey,
+                                           ValueName->Buffer,
+                                           Value);
+
+       break;
+   }
+   case REG_SZ:
+   case REG_MULTI_SZ: {
+       PANSI_STRING    Value;
+
+       status = RegistryQuerySzValue(SourceKey,
+                                     ValueName->Buffer,
+                                     NULL,
+                                     &Value);
+       if (NT_SUCCESS(status)) {
+           (VOID) RegistryUpdateSzValue(DestinationKey,
+                                        ValueName->Buffer,
+                                        Type,
+                                        Value);
+           RegistryFreeSzValue(Value);
+       }
+
+       break;
+   }
+   case REG_BINARY: {
+       PVOID   Value;
+       ULONG   Length;
+
+       status = RegistryQueryBinaryValue(SourceKey,
+                                         ValueName->Buffer,
+                                         &Value,
+                                         &Length);
+       if (NT_SUCCESS(status)) {
+           (VOID) RegistryUpdateBinaryValue(DestinationKey,
+                                            ValueName->Buffer,
+                                            Value,
+                                            Length);
+           if (Length != 0)
+               RegistryFreeBinaryValue(Value);
+       }
+
+       break;
+   }
+   default:
+       ASSERT(FALSE);
+   }
+
+   return STATUS_SUCCESS;
+}
 
 static NTSTATUS
-SettingsCopyIpAddressesValue(
-    IN  PVOID                               Context,
-    IN  HANDLE                              SourceKey,
-    IN  PANSI_STRING                        SourceValueName,
-    IN  ULONG                               Type
+SettingsCopyInterface(
+    IN  PCHAR           InterfacePath,
+    IN  PCHAR           InterfacePrefix,
+    IN  PANSI_STRING    OldGuid,
+    IN  PANSI_STRING    NewGuid
     )
 {
-    PSETTINGS_IP_ADDRESSES_COPY_PARAMETERS  Parameters = Context;
-    ULONG                                   SourceValuePrefixLength;
-    ULONG                                   DestinationValuePrefixLength;
-    ULONG                                   DestinationValueNameLength;
-    PCHAR                                   DestinationValueName;
-    PVOID                                   Value;
-    ULONG                                   ValueLength;
-    NTSTATUS                                status;
+    HANDLE              OldKey;
+    HANDLE              NewKey;
+    PCHAR               OldKeyName;
+    PCHAR               NewKeyName;
+    ULONG               OldKeyLength;
+    ULONG               NewKeyLength;
+    NTSTATUS            status;
+
+    OldKeyLength = (ULONG)(strlen(InterfacePath) +
+                           strlen(InterfacePrefix) +
+                           OldGuid->Length +
+                           1) * sizeof(CHAR);
+    NewKeyLength = (ULONG)(strlen(InterfacePath) +
+                           strlen(InterfacePrefix) +
+                           NewGuid->Length +
+                           1) * sizeof(CHAR);
 
-    if (Type != REG_BINARY)
-        goto done;
+    status = STATUS_NO_MEMORY;
+    OldKeyName = __SettingsAllocate(OldKeyLength);
+    if (OldKeyName == NULL)
+        goto fail1;
 
-    SourceValuePrefixLength = (ULONG)strlen(Parameters->SourceValuePrefix);
-    DestinationValuePrefixLength = 
(ULONG)strlen(Parameters->DestinationValuePrefix);
+    NewKeyName = __SettingsAllocate(NewKeyLength);
+    if (NewKeyName == NULL)
+        goto fail2;
 
-    if (_strnicmp(SourceValueName->Buffer,
-                  Parameters->SourceValuePrefix,
-                  SourceValuePrefixLength) != 0)
-        goto done;
+    status = RtlStringCbPrintfA(OldKeyName,
+                                OldKeyLength,
+                                "%s%s%Z",
+                                InterfacePath,
+                                InterfacePrefix,
+                                OldGuid);
+    if (!NT_SUCCESS(status))
+        goto fail3;
 
-    DestinationValueNameLength = SourceValueName->Length -
-                                 (SourceValuePrefixLength * sizeof (CHAR)) +
-                                 ((DestinationValuePrefixLength + 1) * sizeof 
(CHAR));
+    status = RtlStringCbPrintfA(NewKeyName,
+                                NewKeyLength,
+                                "%s%s%Z",
+                                InterfacePath,
+                                InterfacePrefix,
+                                NewGuid);
+    if (!NT_SUCCESS(status))
+        goto fail4;
 
-    DestinationValueName = __SettingsAllocate(DestinationValueNameLength);
+    status = RegistryOpenSubKey(NULL,
+                                OldKeyName,
+                                KEY_READ,
+                                &OldKey);
+    if (!NT_SUCCESS(status))
+        goto fail5;
 
-    status = STATUS_NO_MEMORY;
-    if (DestinationValueName == NULL)
-        goto fail1;
+    status = RegistryCreateSubKey(NULL,
+                                  NewKeyName,
+                                  REG_OPTION_NON_VOLATILE,
+                                  &NewKey);
+    if (!NT_SUCCESS(status))
+        goto fail6;
 
-    status = RtlStringCbPrintfA(DestinationValueName,
-                                DestinationValueNameLength,
-                                "%s%s",
-                                Parameters->DestinationValuePrefix,
-                                SourceValueName->Buffer + 
SourceValuePrefixLength);
-    ASSERT(NT_SUCCESS(status));
+    status = RegistryEnumerateValues(OldKey,
+                                     SettingsCopyInterfaceValue,
+                                     NewKey);
+    if (!NT_SUCCESS(status))
+        goto fail7;
 
-    Trace("Version%u: %Z -> %s\n",
-          Parameters->Version,
-          SourceValueName,
-          DestinationValueName);
+    RegistryCloseKey(NewKey);
+    RegistryCloseKey(OldKey);
+    __SettingsFree(NewKeyName);
+    __SettingsFree(OldKeyName);
 
-    status = RegistryQueryBinaryValue(SourceKey,
-                                      SourceValueName->Buffer,
-                                      &Value,
-                                      &ValueLength);
-    if (NT_SUCCESS(status)) {
-        (VOID) RegistryUpdateBinaryValue(Parameters->DestinationKey,
-                                         DestinationValueName,
-                                         Value,
-                                         ValueLength);
-        RegistryFreeBinaryValue(Value);
-    }
+    return STATUS_SUCCESS;
 
-    __SettingsFree(DestinationValueName);
+fail7:
+    Error("fail7\n");
 
-done:
-    return STATUS_SUCCESS;
+    RegistryCloseKey(NewKey);
 
-fail1:
-    Error("fail1 (%08x)\n", status);
+fail6:
+    Error("fail6\n");
 
-    return status;
-}
+    RegistryCloseKey(OldKey);
 
-#define IPV6_PATH 
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Nsi\\{eb004a01-9b1a-11d4-9123-0050047759bc}\\10"
+fail5:
+    Error("fail5\n");
 
-#define IPV4_PATH 
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Nsi\\{eb004a00-9b1a-11d4-9123-0050047759bc}\\10"
+fail4:
+    Error("fail4\n");
 
-static NTSTATUS
-SettingsCopyIpAddresses(
-    IN  HANDLE      SettingsKey,
-    IN  UCHAR       Version,
-    IN  PNET_LUID   Luid,
-    IN  BOOLEAN     Save
-    )
-{
-    const CHAR      *Path;
-    HANDLE          Key;
-    ULONG           ValuePrefixLength;
-    PCHAR           ValuePrefix;
-    const CHAR      *SaveKeyName;
-    HANDLE          SaveKey;
-    NTSTATUS        status;
+fail3:
+    Error("fail3\n");
 
-    Trace("====>\n");
+    __SettingsFree(NewKeyName);
 
-    ASSERT(Version == 4 || Version == 6);
-    Path = (Version == 4) ? IPV4_PATH : IPV6_PATH;
+fail2:
+    Error("fail2\n");
 
-    status = RegistryOpenSubKey(NULL,
-                                (PCHAR)Path,
-                                (Save) ? KEY_READ : KEY_ALL_ACCESS,
-                                &Key);
-    if (!NT_SUCCESS(status)) {
-        Info("Version%u: ADDRESSES NOT FOUND\n", Version);
-        goto done;
-    }
+    __SettingsFree(OldKeyName);
 
-    ValuePrefixLength = (ULONG)(((sizeof (NET_LUID) * 2) +
-                                 1) * sizeof (CHAR));
+fail1:
+    Error("fail1 %08x\n", status);
 
-    ValuePrefix = __SettingsAllocate(ValuePrefixLength);
+    return status;
+}
 
-    status = STATUS_NO_MEMORY;
-    if (ValuePrefix == NULL)
-        goto fail1;
+static NTSTATUS
+SettingsCopy(
+    IN  PCHAR           SubKeyName,
+    IN  PANSI_STRING    OldGuid,
+    IN  PNET_LUID       OldLuid,
+    IN  PANSI_STRING    NewGuid,
+    IN  PNET_LUID       NewLuid
+    )
+{
+    HANDLE              SettingsKey;
+    HANDLE              SubKey;
+    NTSTATUS            status;
 
-    status = RtlStringCbPrintfA(ValuePrefix,
-                                ValuePrefixLength,
-                                "%016llX",
-                                Luid->Value);
-    ASSERT(NT_SUCCESS(status));
-
-    SaveKeyName = (Version == 4) ? "IpVersion4Addresses" : 
"IpVersion6Addresses";
-
-    status = (Save) ?
-        RegistryCreateSubKey(SettingsKey,
-                             (PCHAR)SaveKeyName,
-                             REG_OPTION_NON_VOLATILE,
-                             &SaveKey) :
-        RegistryOpenSubKey(SettingsKey,
-                           (PCHAR)SaveKeyName,
-                           KEY_READ,
-                           &SaveKey);
-    if (!NT_SUCCESS(status))
-        goto fail2;
+    Info("VIF/%s: FROM %Z\n", SubKeyName, OldGuid);
+    Info("VIF/%s: TO   %Z\n", SubKeyName, NewGuid);
 
-    if (Save) {
-        SETTINGS_IP_ADDRESSES_COPY_PARAMETERS   Parameters;
+    (VOID) SettingsCopyInterface(INTERFACES_PATH(TCPIP),
+                                 "",
+                                 OldGuid,
+                                 NewGuid);
 
-        Parameters.Version = Version;
-        Parameters.SourceValuePrefix = ValuePrefix;
-        Parameters.DestinationKey = SaveKey;
-        Parameters.DestinationValuePrefix = "LUID";
+    (VOID) SettingsCopyInterface(INTERFACES_PATH(TCPIP6),
+                                 "",
+                                 OldGuid,
+                                 NewGuid);
 
-        status = RegistryEnumerateValues(Key,
-                                         SettingsCopyIpAddressesValue,
-                                         &Parameters);
-    } else { // Restore
-        SETTINGS_IP_ADDRESSES_COPY_PARAMETERS   Parameters;
+    (VOID) SettingsCopyInterface(INTERFACES_PATH(NETBT),
+                                 "Tcpip_",
+                                 OldGuid,
+                                 NewGuid);
 
-        Parameters.Version = Version;
-        Parameters.SourceValuePrefix = "LUID";
-        Parameters.DestinationKey = Key;
-        Parameters.DestinationValuePrefix = ValuePrefix;
+    (VOID) SettingsCopyIpAddresses(4,
+                                   OldLuid,
+                                   NewLuid);
 
-        status = RegistryEnumerateValues(SaveKey,
-                                         SettingsCopyIpAddressesValue,
-                                         &Parameters);
-    }
+    (VOID) SettingsCopyIpAddresses(6,
+                                   OldLuid,
+                                   NewLuid);
 
-    RegistryCloseKey(SaveKey);
+    SettingsKey = DriverGetSettingsKey();
 
-    __SettingsFree(ValuePrefix);
+    status = RegistryCreateSubKey(SettingsKey,
+                                  SubKeyName,
+                                  REG_OPTION_NON_VOLATILE,
+                                  &SubKey);
+    if (!NT_SUCCESS(status))
+        goto fail1;
 
-    RegistryCloseKey(Key);
+    status = RegistryUpdateSzValue(SubKey,
+                                   "NetCfgInstanceId",
+                                   REG_SZ,
+                                   NewGuid);
+    if (!NT_SUCCESS(status))
+        goto fail2;
 
-done:
-    Trace("<====\n");
+    status = RegistryUpdateBinaryValue(SubKey,
+                                       "NetLuid",
+                                       NewLuid,
+                                       sizeof(NET_LUID));
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    RegistryCloseKey(SubKey);
 
     return STATUS_SUCCESS;
 
+fail3:
+    Error("fail3\n");
+
 fail2:
     Error("fail2\n");
 
-    __SettingsFree(ValuePrefix);
+    RegistryCloseKey(SubKey);
 
 fail1:
     Error("fail1 (%08x)\n", status);
 
-    RegistryCloseKey(Key);
-
     return status;
 }
 
-#define INTERFACES_PATH(_Name) 
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\" ## #_Name ## 
"\\Parameters\\Interfaces\\"
-
-static VOID
-SettingsCopy(
-     IN HANDLE      SettingsKey,
-     IN LPGUID      InterfaceGuid,
-     IN PNET_LUID   InterfaceLuid,
-     IN BOOLEAN     Save
-     )
-{
-    Trace("====>\n");
-
-    (VOID) SettingsCopyInterface(SettingsKey,
-                                 "NetBT",
-                                 INTERFACES_PATH(NetBT),
-                                 "Tcpip_",
-                                 InterfaceGuid,
-                                 Save);
-
-    (VOID) SettingsCopyInterface(SettingsKey,
-                                 "Tcpip",
-                                 INTERFACES_PATH(Tcpip),
-                                 "",
-                                 InterfaceGuid,
-                                 Save);
-
-    (VOID) SettingsCopyInterface(SettingsKey,
-                                 "Tcpip6",
-                                 INTERFACES_PATH(Tcpip6),
-                                 "",
-                                 InterfaceGuid,
-                                 Save);
-
-    (VOID) SettingsCopyIpAddresses(SettingsKey,
-                                   4,
-                                   InterfaceLuid,
-                                   Save);
-
-    (VOID) SettingsCopyIpAddresses(SettingsKey,
-                                   6,
-                                   InterfaceLuid,
-                                   Save);
-
-    Trace("<====\n");
-}
-
 NTSTATUS
 SettingsSave(
     IN  PCHAR       SubKeyName,
@@ -543,6 +511,8 @@ SettingsSave(
 {
     HANDLE          SettingsKey;
     HANDLE          SubKey;
+    ANSI_STRING     Ansi;
+    ULONG           HasSettings;
     NTSTATUS        status;
 
     Info("FROM %ws (%ws)\n", Alias, Description);
@@ -556,12 +526,59 @@ SettingsSave(
     if (!NT_SUCCESS(status))
         goto fail1;
 
-    SettingsCopy(SubKey, InterfaceGuid, InterfaceLuid, TRUE);
+    HasSettings = 0;
+    status = RegistryQueryDwordValue(SubKey,
+                                     "HasSettings",
+                                     &HasSettings);
+    if (!NT_SUCCESS(status))
+        HasSettings = 0;
+
+    if (HasSettings != 0)
+        goto done;
+
+    status = __GuidToString(InterfaceGuid, &Ansi);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    Info("FROM %Z\n", Ansi);
+
+    status = RegistryUpdateSzValue(SubKey,
+                                   "NetCfgInstanceId",
+                                   REG_SZ,
+                                   &Ansi);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    status = RegistryUpdateBinaryValue(SubKey,
+                                       "NetLuid",
+                                       InterfaceLuid,
+                                       sizeof(NET_LUID));
+    if (!NT_SUCCESS(status))
+        goto fail4;
+
+    RtlFreeAnsiString(&Ansi);
+
+done:
+    (VOID) RegistryDeleteValue(SubKey,
+                               "HasSettings");
 
     RegistryCloseKey(SubKey);
 
     return STATUS_SUCCESS;
 
+fail4:
+    Error("fail4\n");
+
+fail3:
+    Error("fail3\n");
+
+    RtlFreeAnsiString(&Ansi);
+
+fail2:
+    Error("fail2\n");
+
+    RegistryCloseKey(SubKey);
+
 fail1:
     Error("fail1\n", status);
 
@@ -579,6 +596,10 @@ SettingsRestore(
 {
     HANDLE          SettingsKey;
     HANDLE          SubKey;
+    ANSI_STRING     Ansi;
+    PANSI_STRING    NetCfgInstanceId;
+    PNET_LUID       NetLuid;
+    ULONG           NetLuidLength;
     NTSTATUS        status;
 
     SettingsKey = DriverGetSettingsKey();
@@ -594,15 +615,64 @@ SettingsRestore(
         goto fail1;
     }
 
-    Info("TO %ws (%ws)\n", Alias, Description);
+    status = RegistryQuerySzValue(SubKey,
+                                  "NetCfgInstanceId",
+                                  NULL,
+                                  &NetCfgInstanceId);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    NetLuidLength = 0;
+    status = RegistryQueryBinaryValue(SubKey,
+                                      "NetLuid",
+                                      &NetLuid,
+                                      &NetLuidLength);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    status = __GuidToString(InterfaceGuid, &Ansi);
+    if (!NT_SUCCESS(status))
+        goto fail4;
+
+    if (RtlCompareString(NetCfgInstanceId, &Ansi, TRUE) != 0) {
+        Info("TO %ws (%ws)\n", Alias, Description);
+        Info("TO %Z\n", Ansi);
+
+        SettingsCopy(SubKeyName,
+                     NetCfgInstanceId,
+                     NetLuid,
+                     &Ansi,
+                     InterfaceLuid);
+    }
+
+    RtlFreeAnsiString(&Ansi);
+
+    if (NetLuidLength != 0)
+        RegistryFreeBinaryValue(NetLuid);
 
-    SettingsCopy(SubKey, InterfaceGuid, InterfaceLuid, FALSE);
+    RegistryFreeSzValue(NetCfgInstanceId);
 
     RegistryCloseKey(SubKey);
 
 done:
     return STATUS_SUCCESS;
 
+fail4:
+    Error("fail4\n");
+
+    if (NetLuidLength != 0)
+        RegistryFreeBinaryValue(NetLuid);
+
+fail3:
+    Error("fail3\n");
+
+    RegistryFreeSzValue(NetCfgInstanceId);
+
+fail2:
+    Error("fail2\n");
+
+    RegistryCloseKey(SubKey);
+
 fail1:
     Error("fail1\n", status);
 
-- 
2.32.0.windows.1




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.