]> xenbits.xensource.com Git - people/pauldu/xenvif.git/commitdiff
steal netcfg instance settings
authorPaul Durrant <paul.durrant@citrix.com>
Wed, 2 Mar 2016 16:35:47 +0000 (16:35 +0000)
committerPaul Durrant <paul.durrant@citrix.com>
Fri, 4 Mar 2016 11:09:26 +0000 (11:09 +0000)
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
src/xenvif/pdo.c
src/xenvif/registry.c
src/xenvif/settings.c
src/xenvif/settings.h

index 418c16198ee361ec28410be1cc63ca92bd69c227..1a8340b450018e675514748532806a20e8685220 100644 (file)
@@ -72,6 +72,9 @@ struct _XENVIF_PDO {
     PXENVIF_THREAD              DevicePowerThread;
     PIRP                        DevicePowerIrp;
 
+    HANDLE                      SoftwareKey;
+    HANDLE                      HardwareKey;
+
     PXENVIF_FDO                 Fdo;
     BOOLEAN                     Missing;
     const CHAR                  *Reason;
@@ -757,11 +760,67 @@ PdoGetPermanentAddress(
     return __PdoGetPermanentAddress(Pdo);
 }
 
+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  HANDLE      SoftwareKey,
-    IN  HANDLE      HardwareKey
+    IN  PXENVIF_PDO Pdo
     )
 {
     PANSI_STRING    DriverDesc;
@@ -769,7 +828,7 @@ PdoSetFriendlyName(
     ANSI_STRING     FriendlyName[2];
     NTSTATUS        status;
 
-    status = RegistryQuerySzValue(SoftwareKey,
+    status = RegistryQuerySzValue(__PdoGetSoftwareKey(Pdo),
                                   "DriverDesc",
                                   NULL,
                                   &DriverDesc);
@@ -788,7 +847,7 @@ PdoSetFriendlyName(
     RtlZeroMemory(FriendlyName, sizeof (ANSI_STRING) * 2);
     RtlInitAnsiString(&FriendlyName[0], Buffer);
 
-    status = RegistryUpdateSzValue(HardwareKey,
+    status = RegistryUpdateSzValue(__PdoGetHardwareKey(Pdo),
                                    "FriendlyName",
                                    REG_SZ,
                                    FriendlyName);
@@ -815,8 +874,7 @@ fail1:
 
 static FORCEINLINE NTSTATUS
 __PdoSetCurrentAddress(
-    IN  PXENVIF_PDO Pdo,
-    IN  HANDLE      Key
+    IN  PXENVIF_PDO Pdo
     )
 {
     PANSI_STRING    Ansi;
@@ -824,7 +882,7 @@ __PdoSetCurrentAddress(
 
     RtlFillMemory(Pdo->CurrentAddress.Byte, ETHERNET_ADDRESS_LENGTH, 0xFF);
 
-    status = RegistryQuerySzValue(Key,
+    status = RegistryQuerySzValue(__PdoGetSoftwareKey(Pdo),
                                   "NetworkAddress",
                                   NULL,
                                   &Ansi);
@@ -1106,56 +1164,6 @@ 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,
@@ -1188,9 +1196,6 @@ PdoStartDevice(
     ULONG               Index;
     PMIB_IF_ROW2        Row;
     PIO_STACK_LOCATION  StackLocation;
-    HANDLE              SoftwareKey;
-    HANDLE              HardwareKey;
-    GUID                Guid;
     NTSTATUS            status;
 
     status = STATUS_UNSUCCESSFUL;
@@ -1202,23 +1207,17 @@ PdoStartDevice(
     if (DriverSafeMode())
         goto fail2;
 
-    status = RegistryOpenSoftwareKey(__PdoGetDeviceObject(Pdo),
-                                     KEY_ALL_ACCESS,
-                                     &SoftwareKey);
+    status = __PdoSetSoftwareKey(Pdo);
     if (!NT_SUCCESS(status))
         goto fail3;
 
-    status = RegistryOpenHardwareKey(__PdoGetDeviceObject(Pdo),
-                                     KEY_ALL_ACCESS,
-                                     &HardwareKey);
+    status = __PdoSetHardwareKey(Pdo);
     if (!NT_SUCCESS(status))
         goto fail4;
 
-    (VOID) PdoSetFriendlyName(Pdo,
-                              SoftwareKey,
-                              HardwareKey);
+    (VOID) PdoSetFriendlyName(Pdo);
 
-    status = __PdoSetCurrentAddress(Pdo, SoftwareKey);
+    status = __PdoSetCurrentAddress(Pdo);
     if (!NT_SUCCESS(status))
         goto fail5;
 
@@ -1265,27 +1264,6 @@ 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++) {
-            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);
@@ -1299,8 +1277,6 @@ PdoStartDevice(
 
     __FreeMibTable(Table);
 
-    RegistryCloseKey(SoftwareKey);
-
     return STATUS_SUCCESS;
 
 fail10:
@@ -1313,11 +1289,10 @@ fail10:
 fail9:
     Error("fail9\n");
 
-    (VOID) SettingsSave(SoftwareKey,
-                        Row->Alias,
-                        Row->Description,
-                        &Row->InterfaceGuid,
-                        &Row->InterfaceLuid);
+    (VOID) SettingsStealIdentity(__PdoGetSoftwareKey(Pdo),
+                                 Row->Alias,
+                                 Row->Description,
+                                 &Row->InterfaceGuid);
 
     DriverRequestReboot();
     __FreeMibTable(Table);
@@ -1336,12 +1311,14 @@ fail6:
 fail5:
     Error("fail5\n");
 
-    RegistryCloseKey(HardwareKey);
+    RegistryCloseKey(__PdoGetHardwareKey(Pdo));
+    Pdo->HardwareKey = NULL;
 
 fail4:
     Error("fail4\n");
 
-    RegistryCloseKey(SoftwareKey);
+    RegistryCloseKey(__PdoGetSoftwareKey(Pdo));
+    Pdo->SoftwareKey = NULL;
 
 fail3:
     Error("fail3\n");
@@ -1410,6 +1387,12 @@ 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;
 
@@ -1495,6 +1478,12 @@ PdoRemoveDevice(
 done:
     RtlZeroMemory(&Pdo->CurrentAddress, sizeof (ETHERNET_ADDRESS));
 
+    RegistryCloseKey(__PdoGetHardwareKey(Pdo));
+    Pdo->HardwareKey = NULL;
+
+    RegistryCloseKey(__PdoGetSoftwareKey(Pdo));
+    Pdo->SoftwareKey = NULL;
+
     NeedInvalidate = FALSE;
 
     FdoAcquireMutex(Fdo);
index d994e134694b3b6db5aeed8588c272634cf01ff8..0d3b3c5624ea165e49debbc8f5fdad6a484bf2b9 100644 (file)
@@ -345,49 +345,6 @@ fail1:
     return status;
 }
 
-NTSTATUS
-RegistryDeleteSubKey(
-    IN  PHANDLE         Key,
-    IN  PCHAR           Name
-    )
-{
-    ANSI_STRING         Ansi;
-    UNICODE_STRING      Unicode;
-    HANDLE              SubKey;
-    NTSTATUS            status;
-
-    RtlInitAnsiString(&Ansi, Name);
-
-    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    status = RegistryOpenKey(Key, &Unicode, KEY_ALL_ACCESS, &SubKey);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status = ZwDeleteKey(SubKey);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    ZwClose(SubKey);
-
-    (VOID) ZwFlushKey(Key);
-
-    RtlFreeUnicodeString(&Unicode);
-
-    return STATUS_SUCCESS;
-
-fail3:
-    ZwClose(SubKey);
-
-fail2:
-    RtlFreeUnicodeString(&Unicode);
-
-fail1:
-    return status;
-}
-
 NTSTATUS
 RegistryEnumerateSubKeys(
     IN  HANDLE              Key,
@@ -492,6 +449,64 @@ fail1:
     return status;
 }
 
+static NTSTATUS
+RegistryDeleteSubKeyTree(
+    IN  PVOID           Context,
+    IN  PHANDLE         Key,
+    IN  PANSI_STRING    Name
+    )
+{
+    HANDLE              SubKey;
+    NTSTATUS            status;
+
+    UNREFERENCED_PARAMETER(Context);
+
+    status = RegistryOpenSubKey(Key,
+                                Name->Buffer,
+                                KEY_ALL_ACCESS,
+                                &SubKey);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    (VOID) RegistryEnumerateSubKeys(SubKey,
+                                    RegistryDeleteSubKeyTree,
+                                    NULL);
+
+    status = ZwDeleteKey(SubKey);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    ZwClose(SubKey);
+
+    return STATUS_SUCCESS;
+
+fail2:
+    ZwClose(SubKey);
+
+fail1:
+    return status;
+}
+
+NTSTATUS
+RegistryDeleteSubKey(
+    IN  PHANDLE Key,
+    IN  PCHAR   Name
+    )
+{
+    ANSI_STRING Ansi;
+    NTSTATUS    status;
+
+    RtlInitAnsiString(&Ansi, Name);
+
+    status = RegistryDeleteSubKeyTree(NULL,
+                                      Key,
+                                      &Ansi);
+
+    (VOID) ZwFlushKey(Key);
+
+    return status;
+}
+
 NTSTATUS
 RegistryEnumerateValues(
     IN  HANDLE                      Key,
index 5cb99840cd5bdfcb9e6054d28c0c910366d42f8b..65c84f83b2e59c5dd2faf2c7601a2a72b8f7cc60 100644 (file)
  * SUCH DAMAGE.
  */
 
+#define INITGUID 1
+
 #include <ntddk.h>
 #include <ntstrsafe.h>
+#include <devguid.h>
 
 #include "registry.h"
 #include "driver.h"
@@ -56,35 +59,31 @@ __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
+SettingsCopyValue(
+    IN  HANDLE  DestinationKey,
+    IN  HANDLE  SourceKey,
+    IN  PCHAR   ValueName,
+    IN  ULONG   Type
     )
 {
-    PSETTINGS_INTERFACE_COPY_PARAMETERS Parameters = Context;
-    NTSTATUS                            status;
+    NTSTATUS    status;
 
-    Trace("%s:%Z\n", Parameters->SaveKeyName, ValueName);
+    Trace("%s\n", ValueName);
 
     switch (Type) {
     case REG_DWORD: {
         ULONG   Value;
 
         status = RegistryQueryDwordValue(SourceKey,
-                                         ValueName->Buffer,
+                                         ValueName,
                                          &Value);
-        if (NT_SUCCESS(status))
-            (VOID) RegistryUpdateDwordValue(Parameters->DestinationKey,
-                                            ValueName->Buffer,
-                                            Value);
+        if (!NT_SUCCESS(status))
+            goto fail1;
+
+        (VOID) RegistryUpdateDwordValue(DestinationKey,
+                                        ValueName,
+                                        Value);
 
         break;
     }
@@ -93,16 +92,18 @@ SettingsCopyInterfaceValue(
         PANSI_STRING    Value;
 
         status = RegistryQuerySzValue(SourceKey,
-                                      ValueName->Buffer,
+                                      ValueName,
                                       NULL,
                                       &Value);
-        if (NT_SUCCESS(status)) {
-            (VOID) RegistryUpdateSzValue(Parameters->DestinationKey,
-                                         ValueName->Buffer,
-                                         Type,
-                                         Value);
-            RegistryFreeSzValue(Value);
-        }
+        if (!NT_SUCCESS(status))
+            goto fail1;
+
+        (VOID) RegistryUpdateSzValue(DestinationKey,
+                                     ValueName,
+                                     Type,
+                                     Value);
+
+        RegistryFreeSzValue(Value);
 
         break;
     }
@@ -111,17 +112,18 @@ SettingsCopyInterfaceValue(
         ULONG   Length;
 
         status = RegistryQueryBinaryValue(SourceKey,
-                                          ValueName->Buffer,
+                                          ValueName,
                                           &Value,
                                           &Length);
-        if (NT_SUCCESS(status)) {
-            (VOID) RegistryUpdateBinaryValue(Parameters->DestinationKey,
-                                             ValueName->Buffer,
-                                             Value,
-                                             Length);
-            if (Length != 0)
-                RegistryFreeBinaryValue(Value);
-        }
+        if (!NT_SUCCESS(status))
+            goto fail1;
+
+        (VOID) RegistryUpdateBinaryValue(DestinationKey,
+                                         ValueName,
+                                         Value,
+                                         Length);
+        if (Length != 0)
+            RegistryFreeBinaryValue(Value);
 
         break;
     }
@@ -130,167 +132,148 @@ SettingsCopyInterfaceValue(
     }
 
     return STATUS_SUCCESS;
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
 }
 
+typedef struct _SETTINGS_COPY_SUBKEY_VALUE_PARAMETERS {
+    HANDLE  DestinationKey;
+} SETTINGS_COPY_SUBKEY_VALUE_PARAMETERS, *PSETTINGS_COPY_SUBKEY_VALUE_PARAMETERS;
+
 static NTSTATUS
-SettingsCopyInterface(
-    IN  HANDLE      SettingsKey,
-    IN  PCHAR       SaveKeyName,
-    IN  PCHAR       InterfacesPath,
-    IN  PCHAR       InterfacePrefix,
-    IN  LPGUID      Guid,
-    IN  BOOLEAN     Save
+SettingsCopySubKeyValue(
+    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;
+    PSETTINGS_COPY_SUBKEY_VALUE_PARAMETERS Parameters = Context;
 
-    Trace("====>\n");
+    return SettingsCopyValue(Parameters->DestinationKey,
+                             Key,
+                             ValueName->Buffer,
+                             Type);
+}
+
+static NTSTATUS
+SettingsCopySubKey(
+    IN  HANDLE                              DestinationKey,
+    IN  HANDLE                              SourceKey,
+    IN  PCHAR                               SubKeyName
+    )
+{
+    SETTINGS_COPY_SUBKEY_VALUE_PARAMETERS   Parameters;
+    HANDLE                                  DestinationSubKey;
+    HANDLE                                  SourceSubKey;
+    NTSTATUS                                status;
 
-    status = RtlStringFromGUID(Guid, &Unicode);
+    status = RegistryCreateSubKey(DestinationKey,
+                                  SubKeyName,
+                                  REG_OPTION_NON_VOLATILE,
+                                  &DestinationSubKey);
     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)
+    status = RegistryOpenSubKey(SourceKey,
+                                SubKeyName,
+                                KEY_READ,
+                                &SourceSubKey);
+    if (!NT_SUCCESS(status))
         goto fail2;
 
-    status = RtlStringCbPrintfA(InterfaceName,
-                                Length,
-                                "%wZ",
-                                &Unicode);
-    ASSERT(NT_SUCCESS(status));
+    RtlZeroMemory(&Parameters, sizeof (Parameters));
 
-    status = RegistryOpenSubKey(NULL,
-                                InterfacesPath,
-                                KEY_ALL_ACCESS,
-                                &InterfacesKey);
+    Parameters.DestinationKey = DestinationSubKey;
+
+    status = RegistryEnumerateValues(SourceSubKey,
+                                     SettingsCopySubKeyValue,
+                                     &Parameters);
     if (!NT_SUCCESS(status))
         goto fail3;
 
-    Length = (ULONG)((strlen(InterfacePrefix) +
-                      strlen(InterfaceName) +
-                      1) * sizeof (CHAR));
-
-    KeyName = __SettingsAllocate(Length);
+    RegistryCloseKey(SourceSubKey);
 
-    status = STATUS_NO_MEMORY;
-    if (KeyName == NULL)
-        goto fail4;
+    RegistryCloseKey(DestinationSubKey);
 
-    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;
+    return STATUS_SUCCESS;
 
-    status = (Save) ?
-        RegistryCreateSubKey(SettingsKey,
-                             SaveKeyName,
-                             REG_OPTION_NON_VOLATILE,
-                             &SaveKey) :
-        RegistryOpenSubKey(SettingsKey,
-                           SaveKeyName,
-                           KEY_READ,
-                           &SaveKey);
-    if (!NT_SUCCESS(status))
-        goto fail6;
+fail3:
+    Error("fail3\n");
 
-    if (Save) {
-        SETTINGS_INTERFACE_COPY_PARAMETERS  Parameters;
+    RegistryCloseKey(SourceSubKey);
 
-        Parameters.SaveKeyName = SaveKeyName;
-        Parameters.DestinationKey = SaveKey;
+fail2:
+    Error("fail2\n");
 
-        status = RegistryEnumerateValues(Key,
-                                         SettingsCopyInterfaceValue,
-                                         &Parameters);
-    } else { // Restore
-        SETTINGS_INTERFACE_COPY_PARAMETERS  Parameters;
+    RegistryCloseKey(DestinationSubKey);
 
-        Parameters.SaveKeyName = SaveKeyName;
-        Parameters.DestinationKey = Key;
+fail1:
+    Error("fail1 (%08x)\n", status);
 
-        status = RegistryEnumerateValues(SaveKey,
-                                         SettingsCopyInterfaceValue,
-                                         &Parameters);
-    }
+    return status;
+}
 
-    if (!NT_SUCCESS(status))
-        goto fail7;
+#define CLASS_PATH "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Class"
 
-    RegistryCloseKey(SaveKey);
+static NTSTATUS
+SettingsOpenNetKey(
+    IN  ACCESS_MASK DesiredAccess,
+    OUT PHANDLE     NetKey
+    )
+{
+    HANDLE          ClassKey;
+    UNICODE_STRING  Unicode;
+    ANSI_STRING     Ansi;
+    NTSTATUS        status;
 
-    if (!Save)
-        (VOID) RegistryDeleteSubKey(SettingsKey, SaveKeyName);
+    status = RegistryOpenSubKey(NULL,
+                                CLASS_PATH,
+                                KEY_ALL_ACCESS,
+                                &ClassKey);
+    if (!NT_SUCCESS(status))
+        goto fail1;
 
-    RegistryCloseKey(Key);
+    status = RtlStringFromGUID(&GUID_DEVCLASS_NET, &Unicode);
+    if (!NT_SUCCESS(status))
+        goto fail2;
 
-    __SettingsFree(KeyName);
+    status = RtlUnicodeStringToAnsiString(&Ansi, &Unicode, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail3;
 
-    RegistryCloseKey(InterfacesKey);
+    status = RegistryOpenSubKey(ClassKey,
+                                Ansi.Buffer,
+                                DesiredAccess,
+                                NetKey);
+    if (!NT_SUCCESS(status))
+        goto fail4;
 
-    __SettingsFree(InterfaceName);
+    RtlFreeAnsiString(&Ansi);
 
     RtlFreeUnicodeString(&Unicode);
 
-    Trace("<====\n");
+    RegistryCloseKey(ClassKey);
 
     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);
+    RtlFreeAnsiString(&Ansi);
 
 fail3:
     Error("fail3\n");
 
-    __SettingsFree(InterfaceName);
+    RtlFreeUnicodeString(&Unicode);
 
 fail2:
     Error("fail2\n");
 
-    RtlFreeUnicodeString(&Unicode);
+    RegistryCloseKey(ClassKey);
 
 fail1:
     Error("fail1 (%08x)\n", status);
@@ -298,315 +281,285 @@ 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;
+typedef struct _SETTINGS_MATCH_NET_CFG_INSTANCE_ID_PARAMETERS {
+    ANSI_STRING NetCfgInstanceID;
+    ANSI_STRING SubKeyName;
+} SETTINGS_MATCH_NET_CFG_INSTANCE_ID_PARAMETERS, *PSETTINGS_MATCH_NET_CFG_INSTANCE_ID_PARAMETERS;
 
 static NTSTATUS
-SettingsCopyIpAddressesValue(
-    IN  PVOID                               Context,
-    IN  HANDLE                              SourceKey,
-    IN  PANSI_STRING                        SourceValueName,
-    IN  ULONG                               Type
+SettingsMatchNetCfgInstanceID(
+    IN  PVOID                                       Context,
+    IN  HANDLE                                      Key,
+    IN  PANSI_STRING                                SubKeyName
     )
 {
-    PSETTINGS_IP_ADDRESSES_COPY_PARAMETERS  Parameters = Context;
-    ULONG                                   SourceValuePrefixLength;
-    ULONG                                   DestinationValuePrefixLength;
-    ULONG                                   DestinationValueNameLength;
-    PCHAR                                   DestinationValueName;
-    PVOID                                   Value;
-    ULONG                                   ValueLength;
-    NTSTATUS                                status;
+    PSETTINGS_MATCH_NET_CFG_INSTANCE_ID_PARAMETERS  Parameters = Context;
+    HANDLE                                          SubKey;
+    ANSI_STRING                                     Ansi;
+    ULONG                                           Type;
+    PANSI_STRING                                    Value;
+    NTSTATUS                                        status;
 
-    if (Type != REG_BINARY)
+    Trace("====> (%Z)\n", SubKeyName);
+
+    if (Parameters->SubKeyName.Length != 0)
         goto done;
 
-    SourceValuePrefixLength = (ULONG)strlen(Parameters->SourceValuePrefix);
-    DestinationValuePrefixLength = (ULONG)strlen(Parameters->DestinationValuePrefix);
+    RtlInitAnsiString(&Ansi, "Properties");
 
-    if (_strnicmp(SourceValueName->Buffer,
-                  Parameters->SourceValuePrefix,
-                  SourceValuePrefixLength) != 0)
+    if (RtlCompareString(&Ansi, SubKeyName, TRUE) == 0)
         goto done;
 
-    DestinationValueNameLength = SourceValueName->Length -
-                                 (SourceValuePrefixLength * sizeof (CHAR)) +
-                                 ((DestinationValuePrefixLength + 1) * sizeof (CHAR));
+    status = RegistryOpenSubKey(Key,
+                                SubKeyName->Buffer,
+                                KEY_READ,
+                                &SubKey);
+    if (!NT_SUCCESS(status))
+        goto fail1;
 
-    DestinationValueName = __SettingsAllocate(DestinationValueNameLength);
+    status = RegistryQuerySzValue(SubKey,
+                                  "NetCfgInstanceID",
+                                  &Type,
+                                  &Value);
+    if (!NT_SUCCESS(status))
+        goto fail2;
 
-    status = STATUS_NO_MEMORY;
-    if (DestinationValueName == NULL)
-        goto fail1;
+    status = STATUS_INVALID_PARAMETER;
+    if (Type != REG_SZ)
+        goto fail3;
 
-    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);
+    if (RtlCompareString(&Parameters->NetCfgInstanceID,
+                         &Value[0],
+                         TRUE) == 0) {
+        Parameters->SubKeyName.MaximumLength = SubKeyName->MaximumLength;
+        Parameters->SubKeyName.Buffer = __SettingsAllocate(Parameters->SubKeyName.MaximumLength);
+
+        status = STATUS_NO_MEMORY;
+        if (Parameters->SubKeyName.Buffer == NULL)
+            goto fail4;
+
+        RtlCopyMemory(Parameters->SubKeyName.Buffer,
+                      SubKeyName->Buffer,
+                      SubKeyName->Length);
+
+        Parameters->SubKeyName.Length = SubKeyName->Length;
     }
 
-    __SettingsFree(DestinationValueName);
+    RegistryFreeSzValue(Value);
+
+    RegistryCloseKey(SubKey);
 
 done:
+    Trace("<====\n");
+
     return STATUS_SUCCESS;
 
+fail4:
+    Error("fail4\n");
+
+fail3:
+    Error("fail3\n");
+
+    RegistryFreeSzValue(Value);
+
+fail2:
+    Error("fail2\n");
+
+    RegistryCloseKey(SubKey);
+
 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
+SettingsGetAliasNetInstance(
+    IN  LPGUID                                      NetCfgInstanceID,
+    OUT PANSI_STRING                                SubKeyName
     )
 {
-    const CHAR      *Path;
-    HANDLE          Key;
-    ULONG           ValuePrefixLength;
-    PCHAR           ValuePrefix;
-    const CHAR      *SaveKeyName;
-    HANDLE          SaveKey;
-    NTSTATUS        status;
+    HANDLE                                          NetKey;
+    UNICODE_STRING                                  Unicode;
+    ANSI_STRING                                     Ansi;
+    SETTINGS_MATCH_NET_CFG_INSTANCE_ID_PARAMETERS   Parameters;
+    NTSTATUS                                        status;
 
-    Trace("====>\n");
-
-    ASSERT(Version == 4 || Version == 6);
-    Path = (Version == 4) ? IPV4_PATH : IPV6_PATH;
+    status = SettingsOpenNetKey(KEY_READ, &NetKey);
+    if (!NT_SUCCESS(status))
+        goto fail1;
 
-    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;
-    }
+    status = RtlStringFromGUID(NetCfgInstanceID, &Unicode);
+    if (!NT_SUCCESS(status))
+        goto fail2;
 
-    ValuePrefixLength = (ULONG)(((sizeof (NET_LUID) * 2) +
-                                 1) * sizeof (CHAR));
+    status = RtlUnicodeStringToAnsiString(&Ansi, &Unicode, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail3;
 
-    ValuePrefix = __SettingsAllocate(ValuePrefixLength);
+    RtlZeroMemory(&Parameters, sizeof (Parameters));
 
-    status = STATUS_NO_MEMORY;
-    if (ValuePrefix == NULL)
-        goto fail1;
+    Parameters.NetCfgInstanceID = Ansi;
 
-    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 = RegistryEnumerateSubKeys(NetKey,
+                                      SettingsMatchNetCfgInstanceID,
+                                      &Parameters);
     if (!NT_SUCCESS(status))
-        goto fail2;
-
-    if (Save) {
-        SETTINGS_IP_ADDRESSES_COPY_PARAMETERS   Parameters;
+        goto fail4;
 
-        Parameters.Version = Version;
-        Parameters.SourceValuePrefix = ValuePrefix;
-        Parameters.DestinationKey = SaveKey;
-        Parameters.DestinationValuePrefix = "LUID";
+    status = STATUS_UNSUCCESSFUL;
+    if (Parameters.SubKeyName.Length == 0)
+        goto fail5;
 
-        status = RegistryEnumerateValues(Key,
-                                         SettingsCopyIpAddressesValue,
-                                         &Parameters);
-    } else { // Restore
-        SETTINGS_IP_ADDRESSES_COPY_PARAMETERS   Parameters;
+    Info("%Z\n", &Parameters.SubKeyName);
 
-        Parameters.Version = Version;
-        Parameters.SourceValuePrefix = "LUID";
-        Parameters.DestinationKey = Key;
-        Parameters.DestinationValuePrefix = ValuePrefix;
+    *SubKeyName = Parameters.SubKeyName;
 
-        status = RegistryEnumerateValues(SaveKey,
-                                         SettingsCopyIpAddressesValue,
-                                         &Parameters);
-    }
+    RegistryCloseKey(NetKey);
 
-    RegistryCloseKey(SaveKey);
+    return STATUS_SUCCESS;
 
-    if (!Save)
-        (VOID) RegistryDeleteSubKey(SettingsKey, (PCHAR)SaveKeyName);
+fail5:
+    Error("fail5\n");
 
-    __SettingsFree(ValuePrefix);
+fail4:
+    Error("fail4\n");
 
-    RegistryCloseKey(Key);
+    RtlFreeAnsiString(&Ansi);
 
-done:
-    Trace("<====\n");
+fail3:
+    Error("fail3\n");
 
-    return STATUS_SUCCESS;
+    RtlFreeUnicodeString(&Unicode);
 
 fail2:
     Error("fail2\n");
 
-    __SettingsFree(ValuePrefix);
+    RegistryCloseKey(NetKey);
 
 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
-     )
+static NTSTATUS
+SettingsCopyLinkage(
+    IN HANDLE       DestinationKey,
+    IN HANDLE       SourceKey
+    )
 {
-    HANDLE          SettingsKey;
     NTSTATUS        status;
 
-    Info("FROM %ws (%ws)\n", Alias, Description);
+    Trace("====>\n");
 
-    status = RegistryCreateSubKey(SoftwareKey,
-                                  "Settings",
-                                  REG_OPTION_NON_VOLATILE,
-                                  &SettingsKey);
+    status = SettingsCopyValue(DestinationKey,
+                               SourceKey,
+                               "NetCfgInstanceID",
+                               REG_SZ);
     if (!NT_SUCCESS(status))
         goto fail1;
 
-    SettingsCopy(SettingsKey, InterfaceGuid, InterfaceLuid, TRUE);
+    status = SettingsCopyValue(DestinationKey,
+                               SourceKey,
+                               "NetLuidIndex",
+                               REG_DWORD);
+    if (!NT_SUCCESS(status))
+        goto fail2;
 
-    RegistryCloseKey(SettingsKey);
+    status = SettingsCopySubKey(DestinationKey,
+                                SourceKey,
+                                "Linkage");
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    Trace("<====\n");
 
     return STATUS_SUCCESS;
 
+fail3:
+    Error("fail3\n");
+
+fail2:
+    Error("fail2\n");
+
 fail1:
-    Error("fail1\n", status);
+    Error("fail1 (%08x)\n", status);
 
     return status;
 }
 
 NTSTATUS
-SettingsRestore(
-     IN HANDLE      SoftwareKey,
-     IN PWCHAR      Alias,
-     IN PWCHAR      Description,
-     IN LPGUID      InterfaceGuid,
-     IN PNET_LUID   InterfaceLuid
-     )
+SettingsStealIdentity(
+    IN HANDLE   SoftwareKey,
+    IN PWCHAR   Alias,
+    IN PWCHAR   Description,
+    IN LPGUID   NetCfgInstanceID
+    )
 {
-    HANDLE          SettingsKey;
-    NTSTATUS        status;
+    ANSI_STRING SubKeyName;
+    HANDLE      NetKey;
+    HANDLE      SubKey;
+    NTSTATUS    status;
 
-    status = RegistryOpenSubKey(SoftwareKey,
-                                "Settings",
-                                KEY_ALL_ACCESS,
-                                &SettingsKey);
-    if (!NT_SUCCESS(status)) {
-        if (status == STATUS_OBJECT_NAME_NOT_FOUND)
-            goto done;
+    Info("%ws (%ws)\n", Alias, Description);
 
+    status = SettingsGetAliasNetInstance(NetCfgInstanceID,
+                                         &SubKeyName);
+    if (!NT_SUCCESS(status))
         goto fail1;
-    }
 
-    Info("TO %ws (%ws)\n", Alias, Description);
+    status = RegistryUpdateSzValue(SoftwareKey,
+                                   "AliasNetInstance",
+                                   REG_SZ,
+                                   &SubKeyName);
+    if (!NT_SUCCESS(status))
+        goto fail2;
 
-    SettingsCopy(SettingsKey, InterfaceGuid, InterfaceLuid, FALSE);
+    status = SettingsOpenNetKey(KEY_READ, &NetKey);
+    if (!NT_SUCCESS(status))
+        goto fail3;
 
-    RegistryCloseKey(SettingsKey);
+    status = RegistryOpenSubKey(NetKey,
+                                SubKeyName.Buffer,
+                                KEY_READ,
+                                &SubKey);
+    if (!NT_SUCCESS(status))
+        goto fail4;
+
+    status = SettingsCopyLinkage(SoftwareKey,
+                                 SubKey);
+    if (!NT_SUCCESS(status))
+        goto fail5;
 
-    (VOID) RegistryDeleteSubKey(SoftwareKey, "Settings");
+    RegistryCloseKey(SubKey);
+
+    RegistryCloseKey(NetKey);
+
+    __SettingsFree(SubKeyName.Buffer);
 
-done:
     return STATUS_SUCCESS;
 
+fail5:
+    Error("fail5\n");
+
+    RegistryCloseKey(SubKey);
+
+fail4:
+    Error("fail4\n");
+
+    RegistryCloseKey(NetKey);
+
+fail3:
+    Error("fail3\n");
+
+fail2:
+    Error("fail2\n");
+
+    __SettingsFree(SubKeyName.Buffer);
+
 fail1:
-    Error("fail1\n", status);
+    Error("fail1 (%08x)\n", status);
 
     return status;
 }
index 7bd1824cde70ef915951cf13fbf9c663f71c9c52..08221f296e9cfa6e97add2de509d953cc69bfa8e 100644 (file)
 #define _XENVIF_SETTINGS_H
 
 extern NTSTATUS
-SettingsSave(
+SettingsStealIdentity(
      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
+     IN LPGUID      InterfaceGuid
      );
 
 #endif  // _XENVIF_SETTINGS_H