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

[win-pv-devel] [PATCH] Revert all settings stealing patches



Windows has completely defeated me. There appears to be no way to
duplicate the stack binding of the emulated device without that binding
being removed if XENNET is un-installed, despite clearing all the
relevant registry keys in the DIF_REMOVE pre-process phase.

So, this patch reverts the code back to using the settings copy
mechanism employed in the 8.1 source.

The patches reverted (with some fix-up) are:

32bd2878 "Remove settings code"
70f4bb96 "Re-work identity stealing code"
04c391d9 "Replace copying network settings with identity stealing"

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 src/xenvif/pdo.c             | 208 ++++++++-------
 src/xenvif/settings.c        | 612 +++++++++++++++++++++++++++++++++++++++++++
 src/xenvif/settings.h        |  53 ++++
 vs2012/xenvif/xenvif.vcxproj |   1 +
 vs2013/xenvif/xenvif.vcxproj |   1 +
 5 files changed, 778 insertions(+), 97 deletions(-)
 create mode 100644 src/xenvif/settings.c
 create mode 100644 src/xenvif/settings.h

diff --git a/src/xenvif/pdo.c b/src/xenvif/pdo.c
index 33a75ae..1b773a1 100644
--- a/src/xenvif/pdo.c
+++ b/src/xenvif/pdo.c
@@ -53,6 +53,7 @@
 #include "registry.h"
 #include "thread.h"
 #include "link.h"
+#include "settings.h"
 #include "dbg_print.h"
 #include "assert.h"
 #include "util.h"
@@ -71,9 +72,6 @@ struct _XENVIF_PDO {
     PXENVIF_THREAD              DevicePowerThread;
     PIRP                        DevicePowerIrp;
 
-    HANDLE                      SoftwareKey;
-    HANDLE                      HardwareKey;
-
     PXENVIF_FDO                 Fdo;
     BOOLEAN                     Missing;
     const CHAR                  *Reason;
@@ -787,67 +785,11 @@ __PdoClearPermanentAddress(
     RtlZeroMemory(&Pdo->PermanentAddress, sizeof (ETHERNET_ADDRESS));
 }
 
-static FORCEINLINE NTSTATUS
-__PdoSetSoftwareKey(
-    IN  PXENVIF_PDO Pdo
-    )
-{
-    NTSTATUS        status;
-
-    status = RegistryOpenSoftwareKey(__PdoGetDeviceObject(Pdo),
-                                     KEY_ALL_ACCESS,
-                                     &Pdo->SoftwareKey);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    return STATUS_SUCCESS;
-
-fail1:
-    Error("fail1\n");
-
-    return status;
-}
-
-static FORCEINLINE HANDLE
-__PdoGetSoftwareKey(
-    IN  PXENVIF_PDO Pdo
-    )
-{
-    return Pdo->SoftwareKey;
-}
-
-static FORCEINLINE NTSTATUS
-__PdoSetHardwareKey(
-    IN  PXENVIF_PDO Pdo
-    )
-{
-    NTSTATUS        status;
-
-    status = RegistryOpenHardwareKey(__PdoGetDeviceObject(Pdo),
-                                     KEY_ALL_ACCESS,
-                                     &Pdo->HardwareKey);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    return STATUS_SUCCESS;
-
-fail1:
-    Error("fail1\n");
-
-    return status;
-}
-
-static FORCEINLINE HANDLE
-__PdoGetHardwareKey(
-    IN  PXENVIF_PDO Pdo
-    )
-{
-    return Pdo->HardwareKey;
-}
-
 static NTSTATUS
 PdoSetFriendlyName(
-    IN  PXENVIF_PDO Pdo
+    IN  PXENVIF_PDO Pdo,
+    IN  HANDLE      SoftwareKey,
+    IN  HANDLE      HardwareKey
     )
 {
     PANSI_STRING    DriverDesc;
@@ -855,7 +797,7 @@ PdoSetFriendlyName(
     ANSI_STRING     Ansi[2];
     NTSTATUS        status;
 
-    status = RegistryQuerySzValue(__PdoGetSoftwareKey(Pdo),
+    status = RegistryQuerySzValue(SoftwareKey,
                                   "DriverDesc",
                                   NULL,
                                   &DriverDesc);
@@ -874,7 +816,7 @@ PdoSetFriendlyName(
     RtlZeroMemory(Ansi, sizeof (ANSI_STRING) * 2);
     RtlInitAnsiString(&Ansi[0], Buffer);
 
-    status = RegistryUpdateSzValue(__PdoGetHardwareKey(Pdo),
+    status = RegistryUpdateSzValue(HardwareKey,
                                    "FriendlyName",
                                    REG_SZ,
                                    Ansi);
@@ -901,7 +843,8 @@ fail1:
 
 static FORCEINLINE NTSTATUS
 __PdoSetCurrentAddress(
-    IN  PXENVIF_PDO Pdo
+    IN  PXENVIF_PDO Pdo,
+    IN  HANDLE      Key
     )
 {
     PANSI_STRING    Ansi;
@@ -909,7 +852,7 @@ __PdoSetCurrentAddress(
 
     RtlFillMemory(Pdo->CurrentAddress.Byte, ETHERNET_ADDRESS_LENGTH, 0xFF);
 
-    status = RegistryQuerySzValue(__PdoGetSoftwareKey(Pdo),
+    status = RegistryQuerySzValue(Key,
                                   "NetworkAddress",
                                   NULL,
                                   &Ansi);
@@ -1191,6 +1134,56 @@ PdoS3ToS4(
     Trace("(%s) <====\n", __PdoGetName(Pdo));
 }
 
+static NTSTATUS
+PdoGetInterfaceGuid(
+    IN  PXENVIF_PDO Pdo,
+    IN  HANDLE      Key,
+    OUT LPGUID      Guid
+    )
+{
+    PANSI_STRING    Ansi;
+    UNICODE_STRING  Unicode;
+    NTSTATUS        status;
+
+    UNREFERENCED_PARAMETER(Pdo);
+
+    status = RegistryQuerySzValue(Key,
+                                  "NetCfgInstanceId",
+                                  NULL,
+                                  &Ansi);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi[0], TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    status = RtlGUIDFromString(&Unicode, Guid);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    RtlFreeUnicodeString(&Unicode);
+
+    RegistryFreeSzValue(Ansi);
+
+    return STATUS_SUCCESS;
+
+fail3:
+    Error("fail3\n");
+
+    RtlFreeUnicodeString(&Unicode);
+
+fail2:
+    Error("fail2\n");
+
+    RegistryFreeSzValue(Ansi);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
 static VOID
 PdoUnplugRequest(
     IN  PXENVIF_PDO Pdo,
@@ -1224,8 +1217,10 @@ PdoStartDevice(
     VOID                (*__FreeMibTable)(PVOID);
     PMIB_IF_TABLE2      Table;
     ULONG               Index;
-    PMIB_IF_ROW2        Row;
     PIO_STACK_LOCATION  StackLocation;
+    HANDLE              SoftwareKey;
+    HANDLE              HardwareKey;
+    GUID                Guid;
     NTSTATUS            status;
 
     status = STATUS_UNSUCCESSFUL;
@@ -1235,17 +1230,23 @@ PdoStartDevice(
     if (DriverSafeMode())
         goto fail2;
 
-    status = __PdoSetSoftwareKey(Pdo);
+    status = RegistryOpenSoftwareKey(__PdoGetDeviceObject(Pdo),
+                                     KEY_ALL_ACCESS,
+                                     &SoftwareKey);
     if (!NT_SUCCESS(status))
         goto fail3;
 
-    status = __PdoSetHardwareKey(Pdo);
+    status = RegistryOpenHardwareKey(__PdoGetDeviceObject(Pdo),
+                                     KEY_ALL_ACCESS,
+                                     &HardwareKey);
     if (!NT_SUCCESS(status))
         goto fail4;
 
-    (VOID) PdoSetFriendlyName(Pdo);
+    (VOID) PdoSetFriendlyName(Pdo,
+                              SoftwareKey,
+                              HardwareKey);
 
-    status = __PdoSetCurrentAddress(Pdo);
+    status = __PdoSetCurrentAddress(Pdo, SoftwareKey);
     if (!NT_SUCCESS(status))
         goto fail5;
 
@@ -1271,14 +1272,13 @@ PdoStartDevice(
     // aliasing emulated device, so save its settings.
     //
     for (Index = 0; Index < Table->NumEntries; Index++) {
-        Row = &Table->Table[Index];
+        PMIB_IF_ROW2    Row = &Table->Table[Index];
 
-        Trace("%s: checking %ws (%ws)\n",
-              __PdoGetName(Pdo),
-              Row->Alias,
-              Row->Description);
+        if (!(Row->InterfaceAndOperStatusFlags.HardwareInterface) ||
+            !(Row->InterfaceAndOperStatusFlags.ConnectorPresent))
+            continue;
 
-        if (!Row->InterfaceAndOperStatusFlags.ConnectorPresent)
+        if (Row->OperStatus != IfOperStatusUp)
             continue;
 
         if (Row->PhysicalAddressLength != sizeof (ETHERNET_ADDRESS))
@@ -1289,10 +1289,14 @@ PdoStartDevice(
                    sizeof (ETHERNET_ADDRESS)) != 0)
             continue;
 
-        if (Row->OperStatus != IfOperStatusUp)
-            continue;
+        (VOID) SettingsSave(SoftwareKey,
+                            Row->Alias,
+                            Row->Description,
+                            &Row->InterfaceGuid,
+                            &Row->InterfaceLuid);
 
         Pdo->HasAlias = TRUE;
+        break;
     }
 
     if (Pdo->HasAlias) {
@@ -1302,6 +1306,27 @@ PdoStartDevice(
         goto fail9;
     }
 
+    //
+    // 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)) {
+        for (Index = 0; Index < Table->NumEntries; Index++) {
+            PMIB_IF_ROW2    Row = &Table->Table[Index];
+
+            if (!IsEqualGUID(&Row->InterfaceGuid, &Guid))
+                continue;
+
+            (VOID) SettingsRestore(SoftwareKey,
+                                   Row->Alias,
+                                   Row->Description,
+                                   &Row->InterfaceGuid,
+                                   &Row->InterfaceLuid);
+            break;
+        }
+    }
+
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
 
     status = PdoD3ToD0(Pdo);
@@ -1317,6 +1342,8 @@ PdoStartDevice(
 
     __FreeMibTable(Table);
 
+    RegistryCloseKey(SoftwareKey);
+
     return STATUS_SUCCESS;
 
 fail10:
@@ -1346,14 +1373,12 @@ fail6:
 fail5:
     Error("fail5\n");
 
-    RegistryCloseKey(__PdoGetHardwareKey(Pdo));
-    Pdo->HardwareKey = NULL;
+    RegistryCloseKey(HardwareKey);
 
 fail4:
     Error("fail4\n");
 
-    RegistryCloseKey(__PdoGetSoftwareKey(Pdo));
-    Pdo->SoftwareKey = NULL;
+    RegistryCloseKey(SoftwareKey);
 
 fail3:
     Error("fail3\n");
@@ -1422,12 +1447,6 @@ PdoStopDevice(
 done:
     RtlZeroMemory(&Pdo->CurrentAddress, sizeof (ETHERNET_ADDRESS));
 
-    RegistryCloseKey(__PdoGetHardwareKey(Pdo));
-    Pdo->HardwareKey = NULL;
-
-    RegistryCloseKey(__PdoGetSoftwareKey(Pdo));
-    Pdo->SoftwareKey = NULL;
-
     __PdoSetDevicePnpState(Pdo, Stopped);
     status = STATUS_SUCCESS;
 
@@ -1513,12 +1532,6 @@ PdoRemoveDevice(
 done:
     RtlZeroMemory(&Pdo->CurrentAddress, sizeof (ETHERNET_ADDRESS));
 
-    RegistryCloseKey(__PdoGetHardwareKey(Pdo));
-    Pdo->HardwareKey = NULL;
-
-    RegistryCloseKey(__PdoGetSoftwareKey(Pdo));
-    Pdo->SoftwareKey = NULL;
-
     NeedInvalidate = FALSE;
 
     FdoAcquireMutex(Fdo);
@@ -2804,11 +2817,12 @@ PdoDestroy(
     PDEVICE_OBJECT  PhysicalDeviceObject = Dx->DeviceObject;
     PXENVIF_FDO     Fdo = __PdoGetFdo(Pdo);
 
-    ASSERT3U(__PdoGetDevicePnpState(Pdo), ==, Deleted);
+    ASSERT(!Pdo->UnplugRequested);
 
-    Pdo->UnplugRequested = FALSE;
     Pdo->HasAlias = FALSE;
 
+    ASSERT3U(__PdoGetDevicePnpState(Pdo), ==, Deleted);
+
     ASSERT(__PdoIsMissing(Pdo));
     Pdo->Missing = FALSE;
 
diff --git a/src/xenvif/settings.c b/src/xenvif/settings.c
new file mode 100644
index 0000000..5cb9984
--- /dev/null
+++ b/src/xenvif/settings.c
@@ -0,0 +1,612 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * *   Redistributions of source code must retain the above
+ *     copyright notice, this list of conditions and the
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the
+ *     following disclaimer in the documentation and/or other
+ *     materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <ntddk.h>
+#include <ntstrsafe.h>
+
+#include "registry.h"
+#include "driver.h"
+#include "dbg_print.h"
+#include "assert.h"
+#include "util.h"
+
+#define SETTINGS_TAG 'TTES'
+
+static FORCEINLINE PVOID
+__SettingsAllocate(
+    IN  ULONG   Length
+    )
+{
+    return __AllocatePoolWithTag(NonPagedPool, Length, SETTINGS_TAG);
+}
+
+static FORCEINLINE VOID
+__SettingsFree(
+    IN  PVOID   Buffer
+    )
+{
+    __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
+    )
+{
+    PSETTINGS_INTERFACE_COPY_PARAMETERS Parameters = Context;
+    NTSTATUS                            status;
+
+    Trace("%s:%Z\n", Parameters->SaveKeyName, ValueName);
+
+    switch (Type) {
+    case REG_DWORD: {
+        ULONG   Value;
+
+        status = RegistryQueryDwordValue(SourceKey,
+                                         ValueName->Buffer,
+                                         &Value);
+        if (NT_SUCCESS(status))
+            (VOID) RegistryUpdateDwordValue(Parameters->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(Parameters->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(Parameters->DestinationKey,
+                                             ValueName->Buffer,
+                                             Value,
+                                             Length);
+            if (Length != 0)
+                RegistryFreeBinaryValue(Value);
+        }
+
+        break;
+    }
+    default:
+        ASSERT(FALSE);
+    }
+
+    return STATUS_SUCCESS;
+}
+
+static NTSTATUS
+SettingsCopyInterface(
+    IN  HANDLE      SettingsKey,
+    IN  PCHAR       SaveKeyName,
+    IN  PCHAR       InterfacesPath,
+    IN  PCHAR       InterfacePrefix,
+    IN  LPGUID      Guid,
+    IN  BOOLEAN     Save
+    )
+{
+    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;
+
+    Length = (ULONG)(((Unicode.Length / sizeof (WCHAR)) +
+                      1) * sizeof (CHAR));
+
+    InterfaceName = __SettingsAllocate(Length);
+
+    status = STATUS_NO_MEMORY;
+    if (InterfaceName == NULL)
+        goto fail2;
+
+    status = RtlStringCbPrintfA(InterfaceName,
+                                Length,
+                                "%wZ",
+                                &Unicode);
+    ASSERT(NT_SUCCESS(status));
+
+    status = RegistryOpenSubKey(NULL,
+                                InterfacesPath,
+                                KEY_ALL_ACCESS,
+                                &InterfacesKey);
+    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;
+
+    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);
+    if (!NT_SUCCESS(status))
+        goto fail5;
+
+    status = (Save) ?
+        RegistryCreateSubKey(SettingsKey,
+                             SaveKeyName,
+                             REG_OPTION_NON_VOLATILE,
+                             &SaveKey) :
+        RegistryOpenSubKey(SettingsKey,
+                           SaveKeyName,
+                           KEY_READ,
+                           &SaveKey);
+    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);
+    }
+
+    if (!NT_SUCCESS(status))
+        goto fail7;
+
+    RegistryCloseKey(SaveKey);
+
+    if (!Save)
+        (VOID) RegistryDeleteSubKey(SettingsKey, SaveKeyName);
+
+    RegistryCloseKey(Key);
+
+    __SettingsFree(KeyName);
+
+    RegistryCloseKey(InterfacesKey);
+
+    __SettingsFree(InterfaceName);
+
+    RtlFreeUnicodeString(&Unicode);
+
+    Trace("<====\n");
+
+    return STATUS_SUCCESS;
+
+fail7:
+    Error("fail7\n");
+
+    RegistryCloseKey(SaveKey);
+
+fail6:
+    Error("fail6\n");
+
+    RegistryCloseKey(Key);
+
+fail5:
+    Error("fail5\n");
+
+    __SettingsFree(KeyName);
+
+fail4:
+    Error("fail4\n");
+
+    RegistryCloseKey(InterfacesKey);
+
+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
+SettingsCopyIpAddressesValue(
+    IN  PVOID                               Context,
+    IN  HANDLE                              SourceKey,
+    IN  PANSI_STRING                        SourceValueName,
+    IN  ULONG                               Type
+    )
+{
+    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);
+
+    status = STATUS_NO_MEMORY;
+    if (DestinationValueName == NULL)
+        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);
+    }
+
+    __SettingsFree(DestinationValueName);
+
+done:
+    return STATUS_SUCCESS;
+
+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
+    )
+{
+    const CHAR      *Path;
+    HANDLE          Key;
+    ULONG           ValuePrefixLength;
+    PCHAR           ValuePrefix;
+    const CHAR      *SaveKeyName;
+    HANDLE          SaveKey;
+    NTSTATUS        status;
+
+    Trace("====>\n");
+
+    ASSERT(Version == 4 || Version == 6);
+    Path = (Version == 4) ? IPV4_PATH : IPV6_PATH;
+
+    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;
+    }
+
+    ValuePrefixLength = (ULONG)(((sizeof (NET_LUID) * 2) +
+                                 1) * sizeof (CHAR));
+
+    ValuePrefix = __SettingsAllocate(ValuePrefixLength);
+
+    status = STATUS_NO_MEMORY;
+    if (ValuePrefix == NULL)
+        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);
+    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);
+
+    if (!Save)
+        (VOID) RegistryDeleteSubKey(SettingsKey, (PCHAR)SaveKeyName);
+
+    __SettingsFree(ValuePrefix);
+
+    RegistryCloseKey(Key);
+
+done:
+    Trace("<====\n");
+
+    return STATUS_SUCCESS;
+
+fail2:
+    Error("fail2\n");
+
+    __SettingsFree(ValuePrefix);
+
+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 HANDLE      SoftwareKey,
+     IN PWCHAR      Alias,
+     IN PWCHAR      Description,
+     IN LPGUID      InterfaceGuid,
+     IN PNET_LUID   InterfaceLuid
+     )
+{
+    HANDLE          SettingsKey;
+    NTSTATUS        status;
+
+    Info("FROM %ws (%ws)\n", Alias, Description);
+
+    status = RegistryCreateSubKey(SoftwareKey,
+                                  "Settings",
+                                  REG_OPTION_NON_VOLATILE,
+                                  &SettingsKey);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    SettingsCopy(SettingsKey, InterfaceGuid, InterfaceLuid, TRUE);
+
+    RegistryCloseKey(SettingsKey);
+
+    return STATUS_SUCCESS;
+
+fail1:
+    Error("fail1\n", status);
+
+    return status;
+}
+
+NTSTATUS
+SettingsRestore(
+     IN HANDLE      SoftwareKey,
+     IN PWCHAR      Alias,
+     IN PWCHAR      Description,
+     IN LPGUID      InterfaceGuid,
+     IN PNET_LUID   InterfaceLuid
+     )
+{
+    HANDLE          SettingsKey;
+    NTSTATUS        status;
+
+    status = RegistryOpenSubKey(SoftwareKey,
+                                "Settings",
+                                KEY_ALL_ACCESS,
+                                &SettingsKey);
+    if (!NT_SUCCESS(status)) {
+        if (status == STATUS_OBJECT_NAME_NOT_FOUND)
+            goto done;
+
+        goto fail1;
+    }
+
+    Info("TO %ws (%ws)\n", Alias, Description);
+
+    SettingsCopy(SettingsKey, InterfaceGuid, InterfaceLuid, FALSE);
+
+    RegistryCloseKey(SettingsKey);
+
+    (VOID) RegistryDeleteSubKey(SoftwareKey, "Settings");
+
+done:
+    return STATUS_SUCCESS;
+
+fail1:
+    Error("fail1\n", status);
+
+    return status;
+}
diff --git a/src/xenvif/settings.h b/src/xenvif/settings.h
new file mode 100644
index 0000000..7bd1824
--- /dev/null
+++ b/src/xenvif/settings.h
@@ -0,0 +1,53 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * *   Redistributions of source code must retain the above
+ *     copyright notice, this list of conditions and the
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the
+ *     following disclaimer in the documentation and/or other
+ *     materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _XENVIF_SETTINGS_H
+#define _XENVIF_SETTINGS_H
+
+extern NTSTATUS
+SettingsSave(
+     IN HANDLE      SoftwareKey,
+     IN PWCHAR      Alias,
+     IN PWCHAR      Description,
+     IN LPGUID      InterfaceGuid,
+     IN PNET_LUID   InterfaceLuid
+     );
+
+extern NTSTATUS
+SettingsRestore(
+     IN HANDLE      SoftwareKey,
+     IN PWCHAR      Alias,
+     IN PWCHAR      Description,
+     IN LPGUID      InterfaceGuid,
+     IN PNET_LUID   InterfaceLuid
+     );
+
+#endif  // _XENVIF_SETTINGS_H
diff --git a/vs2012/xenvif/xenvif.vcxproj b/vs2012/xenvif/xenvif.vcxproj
index 2c24e12..170ab53 100644
--- a/vs2012/xenvif/xenvif.vcxproj
+++ b/vs2012/xenvif/xenvif.vcxproj
@@ -77,6 +77,7 @@
     <ClCompile Include="../../src/xenvif/pdo.c" />
     <ClCompile Include="../../src/xenvif/receiver.c" />
     <ClCompile Include="../../src/xenvif/registry.c" />
+    <ClCompile Include="../../src/xenvif/settings.c" />
     <ClCompile Include="../../src/xenvif/thread.c" />
     <ClCompile Include="../../src/xenvif/transmitter.c" />
     <ClCompile Include="../../src/xenvif/controller.c" />
diff --git a/vs2013/xenvif/xenvif.vcxproj b/vs2013/xenvif/xenvif.vcxproj
index b1319cd..9d1dba3 100644
--- a/vs2013/xenvif/xenvif.vcxproj
+++ b/vs2013/xenvif/xenvif.vcxproj
@@ -80,6 +80,7 @@
     <ClCompile Include="../../src/xenvif/pdo.c" />
     <ClCompile Include="../../src/xenvif/receiver.c" />
     <ClCompile Include="../../src/xenvif/registry.c" />
+    <ClCompile Include="../../src/xenvif/settings.c" />
     <ClCompile Include="../../src/xenvif/thread.c" />
     <ClCompile Include="../../src/xenvif/transmitter.c" />
     <ClCompile Include="../../src/xenvif/controller.c" />
-- 
2.5.3


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel

 


Rackspace

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