[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: Mon, 26 Sep 2022 10:55:26 +0100
  • Authentication-results: esa4.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none
  • Cc: Owen Smith <owen.smith@xxxxxxxxxx>
  • Delivery-date: Mon, 26 Sep 2022 09:55:48 +0000
  • Ironport-data: A9a23:qygfuKNhy1+3l9nvrR36l8FynXyQoLVcMsEvi/4bfWQNrUoj1jACz jZMUDqGOquLZWrweNokPd7j8koFvJDWyYQwTwto+SlhQUwRpJueD7x1DKtR0wB+jCHnZBg6h ynLQoCYdKjYdleF+lH3dOCJQUBUjcmgXqD7BPPPJhd/TAplTDZJoR94kqsyj5UAbeKRWmthg vuv5ZyEULOZ82QsaDhMuvje8EkHUMna41v0gHRvPZing3eG/5UlJMp3Db28KXL+Xr5VEoaSL woU5Ojklo9x105F5uKNyt4XQGVTKlLhFVHmZk5tc7qjmnB/Shkaic7XAha+hXB/0F1ll/gpo DlEWAfZpQ0BZsUgk8xFO/VU/r0X0QSrN9YrLFDm2fF/wXEqfFPBk/NFEms/LLY+udtbI3t0x f06BywkO0Xra+KemNpXS8Fpj8UnasLqIJkeqjdryjSx4fQOGM6ZBf+QvJkBgWl21psm8fX2P qL1bRJocxnGJQZKO0sXIJk/gP2plj/0dDgwRFe99fFnvjGKnFIZPL7FK+DNdNC4GNRuzmmlq 2HL1nTEAiw3O4nKodaC2i313bKe9c/hY6oNFbv97uAvjFCNy2g7DBwNSUD9sfS/klS5Wd9UN woT4CVGkEQp3BX1FJ+nBUT++SPa+E5HMzZNLwEkwCzdzIHKyQ+IPU5HcxJjcuYWte0ZWRV/g zdlgOjVLTBotbSUT1eU+bGVsS6+NEApEIMSWcMXZVBbuoe++enfmjqKF48+S/Dt0rUZDBmqm 1i3QD4Ca6L/ZCLh/4Gy5hj5jj2lvfAlpSZlt1yMDgpJAu6UDbNJhrBEC3CBt56sz67DFDFtW UTofODAhN3i9bnXyESwrBwlRdlFHcqtPjzGmkJIFJI87Tmr8HPLVdkOvm0nfx84apdfIGOBj KrvVeR5tfdu0IaCN/crM+pd9exzpUQfKTgVfq+NNYcfCnSAXASG4DtvdSat4owZq2B1yPlXB HtuWZzzZZrsIfg4kWHeqiZ0+eND+x3SMkuIHM6mn0n4i+DGDJNXIJ9cWGazgikCxPvsiG3oH xx3bqNmFz03vDXCXxTq
  • Ironport-hdrordr: A9a23:0yoeiqnHYMZ5gskg1JfI20lZNrnpDfIq3DAbv31ZSRFFG/Fxl6 iV88jzsiWE7wr5OUtQ4OxoV5PgfZqxz/NICMwqTNWftWrdyQ+VxeNZjbcKqgeIc0aVygce79 YET0EXMqyXMbEQt6jHCWeDf+rIuOP3k5yVuQ==
  • 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 Guid and Luid 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      |  98 ++++--
 src/xenvif/settings.c | 728 +++++++++++++++++++++++-------------------
 2 files changed, 479 insertions(+), 347 deletions(-)

diff --git a/src/xenvif/pdo.c b/src/xenvif/pdo.c
index b3a4aae..4a6bfd1 100644
--- a/src/xenvif/pdo.c
+++ b/src/xenvif/pdo.c
@@ -1180,6 +1180,49 @@ fail1:
     return status;
 }
 
+static NTSTATUS
+PdoGetInterfaceLuid(
+    IN  PXENVIF_PDO Pdo,
+    IN  HANDLE      Key,
+    OUT PNET_LUID   Luid
+    )
+{
+    ULONG           Value;
+    NTSTATUS        status;
+
+    UNREFERENCED_PARAMETER(Pdo);
+
+    Luid->Value = 0ull;
+
+    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);
+
+    Luid->Value = 0ull;
+
+    return status;
+}
+
 static VOID
 PdoUnplugRequest(
     IN  PXENVIF_PDO Pdo,
@@ -1216,7 +1259,6 @@ PdoStartDevice(
     PIO_STACK_LOCATION  StackLocation;
     HANDLE              SoftwareKey;
     HANDLE              HardwareKey;
-    ULONG               HasSettings;
     GUID                Guid;
     NTSTATUS            status;
 
@@ -1307,39 +1349,45 @@ 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 device.
+    //
+    status = PdoGetInterfaceGuid(Pdo, SoftwareKey, &Guid);
+    if (NT_SUCCESS(status)) {
+        NET_LUID        Luid;
+        PWCHAR          Alias;
+        PWCHAR          Description;
+
+        RtlZeroMemory(&Luid, sizeof(NET_LUID));
+        Alias = NULL;
+        Description = NULL;
+
+        status = PdoGetInterfaceLuid(Pdo, SoftwareKey, &Luid);
         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 != Luid.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,
+                               &Luid);
     }
 
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
diff --git a/src/xenvif/settings.c b/src/xenvif/settings.c
index 214248b..7483ff3 100644
--- a/src/xenvif/settings.c
+++ b/src/xenvif/settings.c
@@ -40,6 +40,22 @@
 
 #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"
+
+#define NETLUID_STRING_LENGTH 16
+
+typedef struct _SETTINGS_COPY_IP_ADDRESS_PARAMETERS {
+    CHAR        SrcPrefix[NETLUID_STRING_LENGTH + 1];
+    CHAR        DstPrefix[NETLUID_STRING_LENGTH + 1];
+} SETTINGS_COPY_IP_ADDRESS_PARAMETERS, *PSETTINGS_COPY_IP_ADDRESS_PARAMETERS;
+
 static FORCEINLINE PVOID
 __SettingsAllocate(
     IN  ULONG   Length
@@ -56,23 +72,181 @@ __SettingsFree(
     __FreePoolWithTag(Buffer, SETTINGS_TAG);
 }
 
-typedef struct _SETTINGS_INTERFACE_COPY_PARAMETERS {
-    PCHAR   SaveKeyName;
-    HANDLE  DestinationKey;
-} SETTINGS_INTERFACE_COPY_PARAMETERS, *PSETTINGS_INTERFACE_COPY_PARAMETERS;
+static FORCEINLINE NTSTATUS
+__GuidToString(
+    IN  LPGUID          Guid,
+    OUT PANSI_STRING    Ansi
+    )
+{
+    NTSTATUS            status;
+    UNICODE_STRING      Unicode;
+
+    status = RtlStringFromGUID(Guid, &Unicode);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = RtlUnicodeStringToAnsiString(Ansi, &Unicode, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    RtlFreeUnicodeString(&Unicode);
+
+    return STATUS_SUCCESS;
+
+fail2:
+    Error("fail2\n");
+
+    RtlFreeUnicodeString(&Unicode);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
 
 static NTSTATUS
-SettingsCopyInterfaceValue(
-    IN  PVOID                           Context,
-    IN  HANDLE                          SourceKey,
-    IN  PANSI_STRING                    ValueName,
-    IN  ULONG                           Type
+SettingsCopyIpAddressesValue(
+    IN  PVOID                               Context,
+    IN  HANDLE                              Key,
+    IN  PANSI_STRING                        ValueName,
+    IN  ULONG                               Type
+    )
+{
+    PSETTINGS_COPY_IP_ADDRESS_PARAMETERS    Parameters = Context;
+    PVOID                                   Value;
+    ULONG                                   ValueLength;
+    NTSTATUS                                status;
+
+    UNREFERENCED_PARAMETER(Type);
+
+    if (_strnicmp(ValueName->Buffer,
+                  Parameters->SrcPrefix,
+                  NETLUID_STRING_LENGTH) != 0)
+        goto done;
+
+    Trace("    -> %Z\n", ValueName);
+
+    status = RegistryQueryBinaryValue(Key,
+                                      ValueName->Buffer,
+                                      &Value,
+                                      &ValueLength);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = RegistryDeleteValue(Key,
+                                 ValueName->Buffer);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    ASSERT(NETLUID_STRING_LENGTH < ValueName->Length);
+    memcpy(ValueName->Buffer, Parameters->DstPrefix, NETLUID_STRING_LENGTH);
+
+    Trace("    <- %Z\n", ValueName);
+
+    status = RegistryUpdateBinaryValue(Key,
+                                       ValueName->Buffer,
+                                       Value,
+                                       ValueLength);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    if (ValueLength != 0)
+        RegistryFreeBinaryValue(Value);
+
+done:
+    return STATUS_SUCCESS;
+
+fail3:
+    Error("fail3\n");
+
+fail2:
+    Error("fail2\n");
+
+    if (ValueLength != 0)
+        RegistryFreeBinaryValue(Value);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
+static NTSTATUS
+SettingsCopyIpAddresses(
+    IN  ULONG                           Version,
+    IN  PNET_LUID                       OldLuid,
+    IN  PNET_LUID                       NewLuid
     )
 {
-    PSETTINGS_INTERFACE_COPY_PARAMETERS Parameters = Context;
+    SETTINGS_COPY_IP_ADDRESS_PARAMETERS Parameters;
+    HANDLE                              Key;
     NTSTATUS                            status;
 
-    Trace("%s:%Z\n", Parameters->SaveKeyName, ValueName);
+    status = RtlStringCbPrintfA(Parameters.SrcPrefix,
+                                sizeof(Parameters.SrcPrefix),
+                                "%016llx",
+                                _byteswap_uint64(OldLuid->Value));
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = RtlStringCbPrintfA(Parameters.DstPrefix,
+                                sizeof(Parameters.DstPrefix),
+                                "%016llx",
+                                _byteswap_uint64(NewLuid->Value));
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    status = RegistryOpenSubKey(NULL,
+                                (Version == 4) ? IPV4_PATH : IPV6_PATH,
+                                KEY_ALL_ACCESS,
+                                &Key);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    Info("IPv%u: %s -> %s\n",
+         Version,
+         Parameters.SrcPrefix,
+         Parameters.DstPrefix);
+
+    status = RegistryEnumerateValues(Key,
+                                     SettingsCopyIpAddressesValue,
+                                     &Parameters);
+    if (!NT_SUCCESS(status))
+        goto fail4;
+
+    RegistryCloseKey(Key);
+
+    return STATUS_SUCCESS;
+
+fail4:
+    Error("fail4\n");
+
+    RegistryCloseKey(Key);
+
+fail3:
+    Error("fail3\n");
+
+fail2:
+    Error("fail2\n");
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
+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: {
@@ -82,7 +256,7 @@ SettingsCopyInterfaceValue(
                                          ValueName->Buffer,
                                          &Value);
         if (NT_SUCCESS(status))
-            (VOID) RegistryUpdateDwordValue(Parameters->DestinationKey,
+            (VOID) RegistryUpdateDwordValue(DestinationKey,
                                             ValueName->Buffer,
                                             Value);
 
@@ -97,7 +271,7 @@ SettingsCopyInterfaceValue(
                                       NULL,
                                       &Value);
         if (NT_SUCCESS(status)) {
-            (VOID) RegistryUpdateSzValue(Parameters->DestinationKey,
+            (VOID) RegistryUpdateSzValue(DestinationKey,
                                          ValueName->Buffer,
                                          Type,
                                          Value);
@@ -115,7 +289,7 @@ SettingsCopyInterfaceValue(
                                           &Value,
                                           &Length);
         if (NT_SUCCESS(status)) {
-            (VOID) RegistryUpdateBinaryValue(Parameters->DestinationKey,
+            (VOID) RegistryUpdateBinaryValue(DestinationKey,
                                              ValueName->Buffer,
                                              Value,
                                              Length);
@@ -134,160 +308,108 @@ SettingsCopyInterfaceValue(
 
 static NTSTATUS
 SettingsCopyInterface(
-    IN  HANDLE      SettingsKey,
-    IN  PCHAR       SaveKeyName,
-    IN  PCHAR       InterfacesPath,
-    IN  PCHAR       InterfacePrefix,
-    IN  LPGUID      Guid,
-    IN  BOOLEAN     Save
+    IN  PCHAR           InterfacePath,
+    IN  PCHAR           InterfacePrefix,
+    IN  PANSI_STRING    OldGuid,
+    IN  PANSI_STRING    NewGuid
     )
 {
-    UNICODE_STRING  Unicode;
-    ULONG           Length;
-    PCHAR           InterfaceName;
-    HANDLE          InterfacesKey;
-    PCHAR           KeyName;
-    HANDLE          Key;
-    HANDLE          SaveKey;
-    NTSTATUS        status;
-
-    Trace("====>\n");
+    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);
 
-    status = RtlStringFromGUID(Guid, &Unicode);
-    if (!NT_SUCCESS(status))
+    status = STATUS_NO_MEMORY;
+    OldKeyName = __SettingsAllocate(OldKeyLength);
+    if (OldKeyName == NULL)
         goto fail1;
 
-    Length = (ULONG)(((Unicode.Length / sizeof (WCHAR)) +
-                      1) * sizeof (CHAR));
-
-    InterfaceName = __SettingsAllocate(Length);
-
-    status = STATUS_NO_MEMORY;
-    if (InterfaceName == NULL)
+    NewKeyName = __SettingsAllocate(NewKeyLength);
+    if (NewKeyName == NULL)
         goto fail2;
 
-    status = RtlStringCbPrintfA(InterfaceName,
-                                Length,
-                                "%wZ",
-                                &Unicode);
-    ASSERT(NT_SUCCESS(status));
-
-    status = RegistryOpenSubKey(NULL,
-                                InterfacesPath,
-                                KEY_ALL_ACCESS,
-                                &InterfacesKey);
+    status = RtlStringCbPrintfA(OldKeyName,
+                                OldKeyLength,
+                                "%s%s%Z",
+                                InterfacePath,
+                                InterfacePrefix,
+                                OldGuid);
     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)
+    status = RtlStringCbPrintfA(NewKeyName,
+                                NewKeyLength,
+                                "%s%s%Z",
+                                InterfacePath,
+                                InterfacePrefix,
+                                NewGuid);
+    if (!NT_SUCCESS(status))
         goto fail4;
 
-    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 = RegistryOpenSubKey(NULL,
+                                OldKeyName,
+                                KEY_READ,
+                                &OldKey);
     if (!NT_SUCCESS(status))
         goto fail5;
 
-    status = (Save) ?
-        RegistryCreateSubKey(SettingsKey,
-                             SaveKeyName,
-                             REG_OPTION_NON_VOLATILE,
-                             &SaveKey) :
-        RegistryOpenSubKey(SettingsKey,
-                           SaveKeyName,
-                           KEY_READ,
-                           &SaveKey);
+    status = RegistryCreateSubKey(NULL,
+                                  NewKeyName,
+                                  REG_OPTION_NON_VOLATILE,
+                                  &NewKey);
     if (!NT_SUCCESS(status))
         goto fail6;
 
-    if (Save) {
-        SETTINGS_INTERFACE_COPY_PARAMETERS  Parameters;
-
-        Parameters.SaveKeyName = SaveKeyName;
-        Parameters.DestinationKey = SaveKey;
-
-        status = RegistryEnumerateValues(Key,
-                                         SettingsCopyInterfaceValue,
-                                         &Parameters);
-    } else { // Restore
-        SETTINGS_INTERFACE_COPY_PARAMETERS  Parameters;
-
-        Parameters.SaveKeyName = SaveKeyName;
-        Parameters.DestinationKey = Key;
-
-        status = RegistryEnumerateValues(SaveKey,
-                                         SettingsCopyInterfaceValue,
-                                         &Parameters);
-    }
-
+    status = RegistryEnumerateValues(OldKey,
+                                     SettingsCopyInterfaceValue,
+                                     NewKey);
     if (!NT_SUCCESS(status))
         goto fail7;
 
-    RegistryCloseKey(SaveKey);
-
-    RegistryCloseKey(Key);
-
-    __SettingsFree(KeyName);
-
-    RegistryCloseKey(InterfacesKey);
-
-    __SettingsFree(InterfaceName);
-
-    RtlFreeUnicodeString(&Unicode);
-
-    Trace("<====\n");
+    RegistryCloseKey(NewKey);
+    RegistryCloseKey(OldKey);
+    __SettingsFree(NewKeyName);
+    __SettingsFree(OldKeyName);
 
     return STATUS_SUCCESS;
 
 fail7:
     Error("fail7\n");
 
-    RegistryCloseKey(SaveKey);
+    RegistryCloseKey(NewKey);
 
 fail6:
     Error("fail6\n");
 
-    RegistryCloseKey(Key);
+    RegistryCloseKey(OldKey);
 
 fail5:
     Error("fail5\n");
 
-    __SettingsFree(KeyName);
-
 fail4:
     Error("fail4\n");
 
-    RegistryCloseKey(InterfacesKey);
-
 fail3:
     Error("fail3\n");
 
-    __SettingsFree(InterfaceName);
+    __SettingsFree(NewKeyName);
 
 fail2:
     Error("fail2\n");
 
-    RtlFreeUnicodeString(&Unicode);
+    __SettingsFree(OldKeyName);
 
 fail1:
     Error("fail1 (%08x)\n", status);
@@ -295,180 +417,101 @@ fail1:
     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
-SettingsCopyIpAddressesValue(
-    IN  PVOID                               Context,
-    IN  HANDLE                              SourceKey,
-    IN  PANSI_STRING                        SourceValueName,
-    IN  ULONG                               Type
+SettingsStoreCurrent(
+    IN  HANDLE          SubKey,
+    IN  PANSI_STRING    Guid,
+    IN  PNET_LUID       Luid
     )
 {
-    PSETTINGS_IP_ADDRESSES_COPY_PARAMETERS  Parameters = Context;
-    ULONG                                   SourceValuePrefixLength;
-    ULONG                                   DestinationValuePrefixLength;
-    ULONG                                   DestinationValueNameLength;
-    PCHAR                                   DestinationValueName;
-    PVOID                                   Value;
-    ULONG                                   ValueLength;
-    NTSTATUS                                status;
-
-    if (Type != REG_BINARY)
-        goto done;
-
-    SourceValuePrefixLength = (ULONG)strlen(Parameters->SourceValuePrefix);
-    DestinationValuePrefixLength = 
(ULONG)strlen(Parameters->DestinationValuePrefix);
-
-    if (_strnicmp(SourceValueName->Buffer,
-                  Parameters->SourceValuePrefix,
-                  SourceValuePrefixLength) != 0)
-        goto done;
-
-    DestinationValueNameLength = SourceValueName->Length -
-                                 (SourceValuePrefixLength * sizeof (CHAR)) +
-                                 ((DestinationValuePrefixLength + 1) * sizeof 
(CHAR));
 
-    DestinationValueName = __SettingsAllocate(DestinationValueNameLength);
+    NTSTATUS            status;
 
-    status = STATUS_NO_MEMORY;
-    if (DestinationValueName == NULL)
+    status = RegistryUpdateSzValue(SubKey,
+                                   "NetCfgInstanceId",
+                                   REG_SZ,
+                                   Guid);
+    if (!NT_SUCCESS(status))
         goto fail1;
 
-    status = RtlStringCbPrintfA(DestinationValueName,
-                                DestinationValueNameLength,
-                                "%s%s",
-                                Parameters->DestinationValuePrefix,
-                                SourceValueName->Buffer + 
SourceValuePrefixLength);
-    ASSERT(NT_SUCCESS(status));
-
-    Trace("Version%u: %Z -> %s\n",
-          Parameters->Version,
-          SourceValueName,
-          DestinationValueName);
-
-    status = RegistryQueryBinaryValue(SourceKey,
-                                      SourceValueName->Buffer,
-                                      &Value,
-                                      &ValueLength);
-    if (NT_SUCCESS(status)) {
-        (VOID) RegistryUpdateBinaryValue(Parameters->DestinationKey,
-                                         DestinationValueName,
-                                         Value,
-                                         ValueLength);
-        RegistryFreeBinaryValue(Value);
-    }
+    status = RegistryUpdateBinaryValue(SubKey,
+                                       "NetLuid",
+                                       Luid,
+                                       sizeof(NET_LUID));
+    if (!NT_SUCCESS(status))
+        goto fail2;
 
-    __SettingsFree(DestinationValueName);
+    (VOID) RegistryDeleteValue(SubKey,
+                               "HasSettings");
 
-done:
     return STATUS_SUCCESS;
 
+fail2:
+    Error("fail2\n");
+
 fail1:
     Error("fail1 (%08x)\n", status);
 
     return status;
 }
 
-#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 NTSTATUS
-SettingsCopyIpAddresses(
-    IN  HANDLE      SettingsKey,
-    IN  UCHAR       Version,
-    IN  PNET_LUID   Luid,
-    IN  BOOLEAN     Save
-    )
+SettingsCopy(
+    IN  PCHAR           SubKeyName,
+    IN  PANSI_STRING    OldGuid,
+    IN  PNET_LUID       OldLuid,
+    IN  PANSI_STRING    NewGuid,
+    IN  PNET_LUID       NewLuid
+     )
 {
-    const CHAR      *Path;
-    HANDLE          Key;
-    ULONG           ValuePrefixLength;
-    PCHAR           ValuePrefix;
-    const CHAR      *SaveKeyName;
-    HANDLE          SaveKey;
-    NTSTATUS        status;
+    HANDLE              SettingsKey;
+    HANDLE              SubKey;
+    NTSTATUS            status;
 
     Trace("====>\n");
+    Info("VIF/%s: FROM %Z\n", SubKeyName, OldGuid);
+    Info("VIF/%s: TO   %Z\n", SubKeyName, NewGuid);
 
-    ASSERT(Version == 4 || Version == 6);
-    Path = (Version == 4) ? IPV4_PATH : IPV6_PATH;
+    (VOID) SettingsCopyInterface(INTERFACES_PATH(NetBT),
+                                 "Tcpip_",
+                                 OldGuid,
+                                 NewGuid);
 
-    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;
-    }
+    (VOID) SettingsCopyInterface(INTERFACES_PATH(Tcpip),
+                                 "",
+                                 OldGuid,
+                                 NewGuid);
 
-    ValuePrefixLength = (ULONG)(((sizeof (NET_LUID) * 2) +
-                                 1) * sizeof (CHAR));
+    (VOID) SettingsCopyInterface(INTERFACES_PATH(Tcpip6),
+                                 "",
+                                 OldGuid,
+                                 NewGuid);
 
-    ValuePrefix = __SettingsAllocate(ValuePrefixLength);
+    (VOID) SettingsCopyIpAddresses(4,
+                                   OldLuid,
+                                   NewLuid);
 
-    status = STATUS_NO_MEMORY;
-    if (ValuePrefix == NULL)
+    (VOID) SettingsCopyIpAddresses(6,
+                                   OldLuid,
+                                   NewLuid);
+
+    SettingsKey = DriverGetSettingsKey();
+
+    status = RegistryCreateSubKey(SettingsKey,
+                                  SubKeyName,
+                                  REG_OPTION_NON_VOLATILE,
+                                  &SubKey);
+    if (!NT_SUCCESS(status))
         goto fail1;
 
-    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);
+    status = SettingsStoreCurrent(SubKey,
+                                  NewGuid,
+                                  NewLuid);
     if (!NT_SUCCESS(status))
         goto fail2;
 
-    if (Save) {
-        SETTINGS_IP_ADDRESSES_COPY_PARAMETERS   Parameters;
-
-        Parameters.Version = Version;
-        Parameters.SourceValuePrefix = ValuePrefix;
-        Parameters.DestinationKey = SaveKey;
-        Parameters.DestinationValuePrefix = "LUID";
-
-        status = RegistryEnumerateValues(Key,
-                                         SettingsCopyIpAddressesValue,
-                                         &Parameters);
-    } else { // Restore
-        SETTINGS_IP_ADDRESSES_COPY_PARAMETERS   Parameters;
-
-        Parameters.Version = Version;
-        Parameters.SourceValuePrefix = "LUID";
-        Parameters.DestinationKey = Key;
-        Parameters.DestinationValuePrefix = ValuePrefix;
-
-        status = RegistryEnumerateValues(SaveKey,
-                                         SettingsCopyIpAddressesValue,
-                                         &Parameters);
-    }
-
-    RegistryCloseKey(SaveKey);
-
-    __SettingsFree(ValuePrefix);
-
-    RegistryCloseKey(Key);
+    RegistryCloseKey(SubKey);
 
-done:
     Trace("<====\n");
 
     return STATUS_SUCCESS;
@@ -476,62 +519,14 @@ done:
 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,25 +538,60 @@ SettingsSave(
 {
     HANDLE          SettingsKey;
     HANDLE          SubKey;
+    ANSI_STRING     Ansi;
+    ULONG           HasSettings;
     NTSTATUS        status;
 
     Info("FROM %ws (%ws)\n", Alias, Description);
 
+    status = __GuidToString(InterfaceGuid, &Ansi);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
     SettingsKey = DriverGetSettingsKey();
 
-    status = RegistryCreateSubKey(SettingsKey,
-                                  SubKeyName,
-                                  REG_OPTION_NON_VOLATILE,
-                                  &SubKey);
+    status = RegistryOpenSubKey(SettingsKey,
+                                SubKeyName,
+                                KEY_ALL_ACCESS,
+                                &SubKey);
     if (!NT_SUCCESS(status))
-        goto fail1;
+        goto fail2;
+
+    HasSettings = 0;
+    status = RegistryQueryDwordValue(SubKey,
+                                     "HasSettings",
+                                     &HasSettings);
+    if (!NT_SUCCESS(status))
+        HasSettings = 0;
+    if (HasSettings != 0)
+        goto done;
+
+    Info("FROM %Z\n", Ansi);
+    Info("FROM %016llx\n", InterfaceLuid->Value);
+
+    status = SettingsStoreCurrent(SubKey,
+                                  &Ansi,
+                                  InterfaceLuid);
+    if (!NT_SUCCESS(status))
+        goto fail3;
 
-    SettingsCopy(SubKey, InterfaceGuid, InterfaceLuid, TRUE);
+    RtlFreeAnsiString(&Ansi);
 
+done:
     RegistryCloseKey(SubKey);
 
     return STATUS_SUCCESS;
 
+fail3:
+    Error("fail3\n");
+
+    RegistryCloseKey(SubKey);
+
+fail2:
+    Error("fail2\n");
+
+    RtlFreeAnsiString(&Ansi);
+
 fail1:
     Error("fail1\n", status);
 
@@ -579,6 +609,10 @@ SettingsRestore(
 {
     HANDLE          SettingsKey;
     HANDLE          SubKey;
+    ANSI_STRING     Ansi;
+    PANSI_STRING    NetCfgInstanceId;
+    PNET_LUID       NetLuid;
+    ULONG           NetLuidLength;
     NTSTATUS        status;
 
     SettingsKey = DriverGetSettingsKey();
@@ -594,15 +628,65 @@ 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;
 
-    SettingsCopy(SubKey, InterfaceGuid, InterfaceLuid, FALSE);
+    if (RtlCompareString(NetCfgInstanceId, &Ansi, TRUE) != 0) {
+        Info("TO %ws (%ws)\n", Alias, Description);
+        Info("TO %Z\n", Ansi);
+        Info("TO %016llx\n", InterfaceLuid->Value);
+
+        SettingsCopy(SubKeyName,
+                     NetCfgInstanceId,
+                     NetLuid,
+                     &Ansi,
+                     InterfaceLuid);
+    }
+
+    RtlFreeAnsiString(&Ansi);
+
+    if (NetLuidLength != 0)
+        RegistryFreeBinaryValue(NetLuid);
+
+    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®.