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

Re: [XENVIF PATCH 2/3] Fix Registry Isolation issues with Server 2025



Since Driver Verifier's registry isolation detects opening absolute paths to registry keys as a violation (and bugchecks), it's not possible to copy settings from emulated to PV.

On Wed, Jul 24, 2024 at 9:13 AM Paul Durrant <xadimgnik@xxxxxxxxx> wrote:
On 09/07/2024 11:44, Owen Smith wrote:
> Use MmGetSystemRoutineAddress to dynamically get IoOpenDriverRegistryKey,
> which is not present on Server 2016.
> Where possible, use IoOpenDriverRegistryKey to avoid opening absolute registry
> paths, which is a driver verifier violation on Server 2025 WHQL testing.
>
> This does remove PdoSetFriendlyName and SettingsSave/SettingsRestore
> - PdoSetFriendlyName gets an absolute path to the parent of a key opened by an
>    allowed API
> - SettingsSave/SettingsRestore directly manipulate several absolute paths, but
>    due to the recent DeviceID changes, the settings copy code should not be
>    neccessary, as the network connection will not be re-created on driver update.
>

What abou when moving from an emulated device to the PV device? That's
why all the settings copy nastiness was originally implemented... it
wasn't about PV driver update.

> Signed-off-by: Owen Smith <owen.smith@xxxxxxxxx>
> ---
>   src/xenvif/driver.c          | 113 +-----
>   src/xenvif/driver.h          |  10 -
>   src/xenvif/pdo.c             | 151 +-------
>   src/xenvif/registry.c        |  72 +++-
>   src/xenvif/registry.h        |   9 +-
>   src/xenvif/settings.c        | 694 -----------------------------------
>   src/xenvif/settings.h        |  54 ---
>   vs2019/xenvif/xenvif.vcxproj |   1 -
>   vs2022/xenvif/xenvif.vcxproj |   1 -
>   9 files changed, 87 insertions(+), 1018 deletions(-)
>   delete mode 100644 src/xenvif/settings.c
>   delete mode 100644 src/xenvif/settings.h
>
> diff --git a/src/xenvif/driver.c b/src/xenvif/driver.c
> index 3345607..2ac793d 100644
> --- a/src/xenvif/driver.c
> +++ b/src/xenvif/driver.c
> @@ -120,54 +120,6 @@ DriverGetParametersKey(
>       return __DriverGetParametersKey();
>   }
>   
> -static FORCEINLINE VOID
> -__DriverSetAddressesKey(
> -    IN  HANDLE  Key
> -    )
> -{
> -    Driver.AddressesKey = Key;
> -}
> -
> -static FORCEINLINE HANDLE
> -__DriverGetAddressesKey(
> -    VOID
> -    )
> -{
> -    return Driver.AddressesKey;
> -}
> -
> -HANDLE
> -DriverGetAddressesKey(
> -    VOID
> -    )
> -{
> -    return __DriverGetAddressesKey();
> -}
> -
> -static FORCEINLINE VOID
> -__DriverSetSettingsKey(
> -    IN  HANDLE  Key
> -    )
> -{
> -    Driver.SettingsKey = Key;
> -}
> -
> -static FORCEINLINE HANDLE
> -__DriverGetSettingsKey(
> -    VOID
> -    )
> -{
> -    return Driver.SettingsKey;
> -}
> -
> -HANDLE
> -DriverGetSettingsKey(
> -    VOID
> -    )
> -{
> -    return __DriverGetSettingsKey();
> -}
> -
>   #define MAXNAMELEN  256
>   
>   static FORCEINLINE VOID
> @@ -265,8 +217,6 @@ DriverUnload(
>       IN  PDRIVER_OBJECT  DriverObject
>       )
>   {
> -    HANDLE              SettingsKey;
> -    HANDLE              AddressesKey;
>       HANDLE              ParametersKey;
>   
>       ASSERT3P(DriverObject, ==, __DriverGetDriverObject());
> @@ -275,16 +225,6 @@ DriverUnload(
>   
>       Driver.NeedReboot = FALSE;
>   
> -    SettingsKey = __DriverGetSettingsKey();
> -    __DriverSetSettingsKey(NULL);
> -
> -    RegistryCloseKey(SettingsKey);
> -
> -    AddressesKey = __DriverGetAddressesKey();
> -    __DriverSetAddressesKey(NULL);
> -
> -    RegistryCloseKey(AddressesKey);
> -
>       ParametersKey = __DriverGetParametersKey();
>       __DriverSetParametersKey(NULL);
>   
> @@ -401,10 +341,7 @@ DriverEntry(
>       IN  PUNICODE_STRING RegistryPath
>       )
>   {
> -    HANDLE              ServiceKey;
>       HANDLE              ParametersKey;
> -    HANDLE              AddressesKey;
> -    HANDLE              SettingsKey;
>       ULONG               Index;
>       NTSTATUS            status;
>   
> @@ -428,43 +365,16 @@ DriverEntry(
>            MONTH,
>            YEAR);
>   
> -    status = RegistryInitialize(RegistryPath);
> +    status = RegistryInitialize(DriverObject, RegistryPath);
>       if (!NT_SUCCESS(status))
>           goto fail1;
>   
> -    status = RegistryOpenServiceKey(KEY_ALL_ACCESS, &ServiceKey);
> +    status = RegistryOpenParametersKey(KEY_READ, &ParametersKey);
>       if (!NT_SUCCESS(status))
>           goto fail2;
>   
> -    status = RegistryOpenSubKey(ServiceKey,
> -                                "Parameters",
> -                                KEY_READ,
> -                                &ParametersKey);
> -    if (!NT_SUCCESS(status))
> -        goto fail3;
> -
>       __DriverSetParametersKey(ParametersKey);
>   
> -    status = RegistryCreateSubKey(ServiceKey,
> -                                  "Addresses",
> -                                  REG_OPTION_VOLATILE,
> -                                  &AddressesKey);
> -    if (!NT_SUCCESS(status))
> -        goto fail4;
> -
> -    __DriverSetAddressesKey(AddressesKey);
> -
> -    status = RegistryCreateSubKey(ServiceKey,
> -                                  "Settings",
> -                                  REG_OPTION_NON_VOLATILE,
> -                                  &SettingsKey);
> -    if (!NT_SUCCESS(status))
> -        goto fail5;
> -
> -    __DriverSetSettingsKey(SettingsKey);
> -
> -    RegistryCloseKey(ServiceKey);
> -
>       DriverObject->DriverExtension->AddDevice = AddDevice;
>   
>       for (Index = 0; Index <= IRP_MJ_MAXIMUM_FUNCTION; Index++) {
> @@ -477,25 +387,6 @@ DriverEntry(
>   
>       return STATUS_SUCCESS;
>   
> -fail5:
> -    Error("fail5\n");
> -
> -    __DriverSetAddressesKey(NULL);
> -
> -    RegistryCloseKey(AddressesKey);
> -
> -fail4:
> -    Error("fail4\n");
> -
> -    __DriverSetParametersKey(NULL);
> -
> -    RegistryCloseKey(ParametersKey);
> -
> -fail3:
> -    Error("fail3\n");
> -
> -    RegistryCloseKey(ServiceKey);
> -
>   fail2:
>       Error("fail2\n");
>   
> diff --git a/src/xenvif/driver.h b/src/xenvif/driver.h
> index b5b9a3d..a9b47d4 100644
> --- a/src/xenvif/driver.h
> +++ b/src/xenvif/driver.h
> @@ -48,16 +48,6 @@ DriverGetParametersKey(
>       VOID
>       );
>   
> -extern HANDLE
> -DriverGetAddressesKey(
> -    VOID
> -    );
> -
> -extern HANDLE
> -DriverGetSettingsKey(
> -    VOID
> -    );
> -
>   extern VOID
>   DriverRequestReboot(
>       VOID
> diff --git a/src/xenvif/pdo.c b/src/xenvif/pdo.c
> index 8ec9814..51cbd97 100644
> --- a/src/xenvif/pdo.c
> +++ b/src/xenvif/pdo.c
> @@ -54,7 +54,6 @@
>   #include "registry.h"
>   #include "thread.h"
>   #include "link.h"
> -#include "settings.h"
>   #include "dbg_print.h"
>   #include "assert.h"
>   #include "util.h"
> @@ -727,30 +726,16 @@ __PdoSetPermanentAddress(
>       IN  PCHAR       Buffer
>       )
>   {
> -    ANSI_STRING     Ansi[2];
>       NTSTATUS        status;
>   
>       status = __PdoParseAddress(Buffer, &Pdo->PermanentAddress);
>       if (!NT_SUCCESS(status))
>           goto fail1;
>   
> -    RtlZeroMemory(Ansi, sizeof (ANSI_STRING) * 2);
> -    RtlInitAnsiString(&Ansi[0], Buffer);
> -
> -    status = RegistryUpdateSzValue(DriverGetAddressesKey(),
> -                                   __PdoGetName(Pdo),
> -                                   REG_SZ,
> -                                   Ansi);
> -    if (!NT_SUCCESS(status))
> -        goto fail2;
> -
> -    Info("%s: %Z\n", __PdoGetName(Pdo), &Ansi[0]);
> +    Info("%s: %s\n", __PdoGetName(Pdo), Buffer);
>   
>       return STATUS_SUCCESS;
>   
> -fail2:
> -    Error("fail2\n");
> -
>   fail1:
>       Error("fail1 (%08x)\n", status);
>   
> @@ -778,68 +763,9 @@ __PdoClearPermanentAddress(
>       IN  PXENVIF_PDO Pdo
>       )
>   {
> -    (VOID) RegistryDeleteValue(DriverGetAddressesKey(),
> -                               __PdoGetName(Pdo));
> -
>       RtlZeroMemory(&Pdo->PermanentAddress, sizeof (ETHERNET_ADDRESS));
>   }
>   
> -static NTSTATUS
> -PdoSetFriendlyName(
> -    IN  PXENVIF_PDO Pdo,
> -    IN  HANDLE      SoftwareKey,
> -    IN  HANDLE      HardwareKey
> -    )
> -{
> -    PANSI_STRING    DriverDesc;
> -    CHAR            Buffer[MAXNAMELEN];
> -    ANSI_STRING     Ansi[2];
> -    NTSTATUS        status;
> -
> -    status = RegistryQuerySzValue(SoftwareKey,
> -                                  "DriverDesc",
> -                                  NULL,
> -                                  &DriverDesc);
> -    if (!NT_SUCCESS(status))
> -        goto fail1;
> -
> -    status = RtlStringCbPrintfA(Buffer,
> -                                MAXNAMELEN,
> -                                "%Z #%s",
> -                                &DriverDesc[0],
> -                                __PdoGetName(Pdo)
> -                                );
> -    if (!NT_SUCCESS(status))
> -        goto fail2;
> -
> -    RtlZeroMemory(Ansi, sizeof (ANSI_STRING) * 2);
> -    RtlInitAnsiString(&Ansi[0], Buffer);
> -
> -    status = RegistryUpdateSzValue(HardwareKey,
> -                                   "FriendlyName",
> -                                   REG_SZ,
> -                                   Ansi);
> -    if (!NT_SUCCESS(status))
> -        goto fail3;
> -
> -    Info("%s: %Z\n", __PdoGetName(Pdo), &Ansi[0]);
> -
> -    RegistryFreeSzValue(DriverDesc);
> -
> -    return STATUS_SUCCESS;
> -
> -fail3:
> -    Error("fail3\n");
> -
> -fail2:
> -    Error("fail2\n");
> -
> -fail1:
> -    Error("fail1 (%08x)\n", status);
> -
> -    return status;
> -}
> -
>   static FORCEINLINE NTSTATUS
>   __PdoSetCurrentAddress(
>       IN  PXENVIF_PDO Pdo,
> @@ -1276,15 +1202,13 @@ PdoUnplugRequested(
>   
>   static FORCEINLINE NTSTATUS
>   PdoParseMibTable(
> -    IN  PXENVIF_PDO     Pdo,
> -    IN  HANDLE          SoftwareKey
> +    IN  PXENVIF_PDO     Pdo
>       )
>   {
>       NTSTATUS            (*__GetIfTable2)(PMIB_IF_TABLE2 *);
>       VOID                (*__FreeMibTable)(PVOID);
>       PMIB_IF_TABLE2      Table;
>       ULONG               Index;
> -    GUID                Guid;
>       NTSTATUS            status;
>   
>       status = LinkGetRoutineAddress("netio.sys",
> @@ -1330,56 +1254,10 @@ PdoParseMibTable(
>           if (Row->OperStatus != IfOperStatusUp)
>               continue;
>   
> -        (VOID) SettingsSave(__PdoGetName(Pdo),
> -                            Row->Alias,
> -                            Row->Description,
> -                            &Row->InterfaceGuid,
> -                            &Row->InterfaceLuid);
> -
>           status = STATUS_PNP_REBOOT_REQUIRED;
>           goto fail4;
>       }
>   
> -    //
> -    // 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];
> -
> -                Trace("%s: CHECKING %ws (%ws)\n",
> -                    __PdoGetName(Pdo),
> -                    Row->Alias,
> -                    Row->Description);
> -
> -                if (Row->InterfaceLuid.Value != Luid.Value)
> -                    continue;
> -
> -                Alias = Row->Alias;
> -                Description = Row->Description;
> -                break;
> -            }
> -        }
> -
> -        (VOID) SettingsRestore(__PdoGetName(Pdo),
> -                               Alias,
> -                               Description,
> -                               &Guid,
> -                               &Luid);
> -    }
> -
>       __FreeMibTable(Table);
>   
>       return STATUS_SUCCESS;
> @@ -1408,7 +1286,6 @@ PdoStartDevice(
>       )
>   {
>       HANDLE              SoftwareKey;
> -    HANDLE              HardwareKey;
>       NTSTATUS            status;
>   
>       status = STATUS_UNSUCCESSFUL;
> @@ -1421,21 +1298,11 @@ PdoStartDevice(
>       if (!NT_SUCCESS(status))
>           goto fail2;
>   
> -    status = RegistryOpenHardwareKey(__PdoGetDeviceObject(Pdo),
> -                                     KEY_ALL_ACCESS,
> -                                     &HardwareKey);
> -    if (!NT_SUCCESS(status))
> -        goto fail3;
> -
> -    (VOID) PdoSetFriendlyName(Pdo,
> -                              SoftwareKey,
> -                              HardwareKey);
> -
>       status = __PdoSetCurrentAddress(Pdo, SoftwareKey);
>       if (!NT_SUCCESS(status))
> -        goto fail4;
> +        goto fail3;
>   
> -    status = PdoParseMibTable(Pdo, SoftwareKey);
> +    status = PdoParseMibTable(Pdo);
>       if (status == STATUS_PNP_REBOOT_REQUIRED || !PdoUnplugRequested(Pdo)) {
>           PdoUnplugRequest(Pdo, TRUE); // fix unplug reference count
>           DriverRequestReboot();
> @@ -1445,7 +1312,7 @@ PdoStartDevice(
>   
>       status = PdoD3ToD0(Pdo);
>       if (!NT_SUCCESS(status))
> -        goto fail5;
> +        goto fail4;
>   
>       PdoUnplugRequest(Pdo, TRUE);
>   
> @@ -1454,20 +1321,14 @@ PdoStartDevice(
>       Irp->IoStatus.Status = STATUS_SUCCESS;
>       IoCompleteRequest(Irp, IO_NO_INCREMENT);
>   
> -    RegistryCloseKey(HardwareKey);
>       RegistryCloseKey(SoftwareKey);
>   
>       return STATUS_SUCCESS;
>   
> -fail5:
> -    Error("fail5\n");
> -
> -    RtlZeroMemory(&Pdo->CurrentAddress, sizeof (ETHERNET_ADDRESS));
> -
>   fail4:
>       Error("fail4\n");
>   
> -    RegistryCloseKey(HardwareKey);
> +    RtlZeroMemory(&Pdo->CurrentAddress, sizeof (ETHERNET_ADDRESS));
>   
>   fail3:
>       Error("fail3\n");
> diff --git a/src/xenvif/registry.c b/src/xenvif/registry.c
> index 8f84818..792ce03 100644
> --- a/src/xenvif/registry.c
> +++ b/src/xenvif/registry.c
> @@ -38,8 +38,13 @@
>   
>   #define REGISTRY_TAG 'GERX'
>   
> +static PDRIVER_OBJECT   RegistryDriverObject;
>   static UNICODE_STRING   RegistryPath;
>   
> +typedef NTSTATUS(*IOOPENDRIVERREGISTRYKEY)(PDRIVER_OBJECT, DRIVER_REGKEY_TYPE, ACCESS_MASK, ULONG, PHANDLE);
> +
> +static IOOPENDRIVERREGISTRYKEY __IoOpenDriverRegistryKey;
> +
>   static FORCEINLINE PVOID
>   __RegistryAllocate(
>       IN  ULONG   Length
> @@ -58,9 +63,12 @@ __RegistryFree(
>   
>   NTSTATUS
>   RegistryInitialize(
> -    IN PUNICODE_STRING  Path
> +    IN  PDRIVER_OBJECT  DriverObject,
> +    IN  PUNICODE_STRING Path
>       )
>   {
> +    UNICODE_STRING      Unicode;
> +    PVOID               Func;
>       NTSTATUS            status;
>   
>       ASSERT3P(RegistryPath.Buffer, ==, NULL);
> @@ -69,6 +77,16 @@ RegistryInitialize(
>       if (!NT_SUCCESS(status))
>           goto fail1;
>   
> +    ASSERT3P(RegistryDriverObject, ==, NULL);
> +    RegistryDriverObject = DriverObject;
> +
> +    ASSERT3P(__IoOpenDriverRegistryKey, ==, NULL);
> +    RtlInitUnicodeString(&Unicode, L"IoOpenDriverRegistryKey");
> +
> +    Func = MmGetSystemRoutineAddress(&Unicode);
> +    if (Func != NULL)
> +        __IoOpenDriverRegistryKey = (IOOPENDRIVERREGISTRYKEY)Func;
> +
>       return STATUS_SUCCESS;
>   
>   fail1:
> @@ -82,6 +100,10 @@ RegistryTeardown(
>       VOID
>       )
>   {
> +    __IoOpenDriverRegistryKey = NULL;
> +
> +    RegistryDriverObject = NULL;
> +
>       RtlFreeUnicodeString(&RegistryPath);
>       RegistryPath.Buffer = NULL;
>       RegistryPath.MaximumLength = RegistryPath.Length = 0;
> @@ -266,6 +288,54 @@ RegistryCreateServiceKey(
>       return RegistryCreateKey(NULL, &RegistryPath, REG_OPTION_NON_VOLATILE, Key);
>   }
>   
> +NTSTATUS
> +RegistryOpenParametersKey(
> +    IN  ACCESS_MASK     DesiredAccess,
> +    OUT PHANDLE         Key
> +    )
> +{
> +    HANDLE              ServiceKey;
> +    NTSTATUS            status;
> +
> +    if (__IoOpenDriverRegistryKey != NULL) {
> +        status = __IoOpenDriverRegistryKey(RegistryDriverObject,
> +                                           DriverRegKeyParameters,
> +                                           DesiredAccess,
> +                                           0,
> +                                           Key);
> +        if (!NT_SUCCESS(status))
> +            goto fail1;
> +
> +        goto done;
> +    }
> +
> +    status = RegistryOpenKey(NULL, &RegistryPath, DesiredAccess, &ServiceKey);
> +    if (!NT_SUCCESS(status))
> +        goto fail2;
> +
> +    status = RegistryOpenSubKey(ServiceKey, "Parameters", DesiredAccess, Key);
> +    if (!NT_SUCCESS(status))
> +        goto fail3;
> +
> +    RegistryCloseKey(ServiceKey);
> +
> +done:
> +    return STATUS_SUCCESS;
> +
> +fail3:
> +    Error("fail3\n");
> +
> +    RegistryCloseKey(ServiceKey);
> +
> +fail2:
> +    Error("fail2\n");
> +
> +fail1:
> +    Error("fail1 %08x\n", status);
> +
> +    return status;
> +}
> +
>   NTSTATUS
>   RegistryOpenSoftwareKey(
>       IN  PDEVICE_OBJECT  DeviceObject,
> diff --git a/src/xenvif/registry.h b/src/xenvif/registry.h
> index c656806..60c50e8 100644
> --- a/src/xenvif/registry.h
> +++ b/src/xenvif/registry.h
> @@ -37,7 +37,8 @@
>   
>   extern NTSTATUS
>   RegistryInitialize(
> -    IN PUNICODE_STRING  Path
> +    IN  PDRIVER_OBJECT  DriverObject,
> +    IN  PUNICODE_STRING Path
>       );
>   
>   extern VOID
> @@ -72,6 +73,12 @@ RegistryCreateServiceKey(
>       OUT PHANDLE     Key
>       );
>   
> +extern NTSTATUS
> +RegistryOpenParametersKey(
> +    IN  ACCESS_MASK     DesiredAccess,
> +    OUT PHANDLE         Key
> +    );
> +
>   extern NTSTATUS
>   RegistryOpenSoftwareKey(
>       IN  PDEVICE_OBJECT  DeviceObject,
> diff --git a/src/xenvif/settings.c b/src/xenvif/settings.c
> deleted file mode 100644
> index 4dd4ec4..0000000
> --- a/src/xenvif/settings.c
> +++ /dev/null
> @@ -1,694 +0,0 @@
> -/* Copyright (c) Xen Project.
> - * Copyright (c) Cloud Software Group, 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'
> -
> -#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
> -    )
> -{
> -    return __AllocatePoolWithTag(NonPagedPool, Length, SETTINGS_TAG);
> -}
> -
> -static FORCEINLINE VOID
> -__SettingsFree(
> -    IN  PVOID   Buffer
> -    )
> -{
> -    __FreePoolWithTag(Buffer, SETTINGS_TAG);
> -}
> -
> -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
> -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
> -    )
> -{
> -    SETTINGS_COPY_IP_ADDRESS_PARAMETERS Parameters;
> -    HANDLE                              Key;
> -    NTSTATUS                            status;
> -
> -    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: {
> -        ULONG   Value;
> -
> -        status = RegistryQueryDwordValue(SourceKey,
> -                                         ValueName->Buffer,
> -                                         &Value);
> -        if (NT_SUCCESS(status))
> -            (VOID) RegistryUpdateDwordValue(DestinationKey,
> -                                            ValueName->Buffer,
> -                                            Value);
> -
> -        break;
> -    }
> -    case REG_SZ:
> -    case REG_MULTI_SZ: {
> -        PANSI_STRING    Value;
> -
> -        status = RegistryQuerySzValue(SourceKey,
> -                                      ValueName->Buffer,
> -                                      NULL,
> -                                      &Value);
> -        if (NT_SUCCESS(status)) {
> -            (VOID) RegistryUpdateSzValue(DestinationKey,
> -                                         ValueName->Buffer,
> -                                         Type,
> -                                         Value);
> -            RegistryFreeSzValue(Value);
> -        }
> -
> -        break;
> -    }
> -    case REG_BINARY: {
> -        PVOID   Value;
> -        ULONG   Length;
> -
> -        status = RegistryQueryBinaryValue(SourceKey,
> -                                          ValueName->Buffer,
> -                                          &Value,
> -                                          &Length);
> -        if (NT_SUCCESS(status)) {
> -            (VOID) RegistryUpdateBinaryValue(DestinationKey,
> -                                             ValueName->Buffer,
> -                                             Value,
> -                                             Length);
> -            if (Length != 0)
> -                RegistryFreeBinaryValue(Value);
> -        }
> -
> -        break;
> -    }
> -    default:
> -        ASSERT(FALSE);
> -    }
> -
> -    return STATUS_SUCCESS;
> -}
> -
> -static NTSTATUS
> -SettingsCopyInterface(
> -    IN  PCHAR           InterfacePath,
> -    IN  PCHAR           InterfacePrefix,
> -    IN  PANSI_STRING    OldGuid,
> -    IN  PANSI_STRING    NewGuid
> -    )
> -{
> -    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 = STATUS_NO_MEMORY;
> -    OldKeyName = __SettingsAllocate(OldKeyLength);
> -    if (OldKeyName == NULL)
> -        goto fail1;
> -
> -    NewKeyName = __SettingsAllocate(NewKeyLength);
> -    if (NewKeyName == NULL)
> -        goto fail2;
> -
> -    status = RtlStringCbPrintfA(OldKeyName,
> -                                OldKeyLength,
> -                                "%s%s%Z",
> -                                InterfacePath,
> -                                InterfacePrefix,
> -                                OldGuid);
> -    if (!NT_SUCCESS(status))
> -        goto fail3;
> -
> -    status = RtlStringCbPrintfA(NewKeyName,
> -                                NewKeyLength,
> -                                "%s%s%Z",
> -                                InterfacePath,
> -                                InterfacePrefix,
> -                                NewGuid);
> -    if (!NT_SUCCESS(status))
> -        goto fail4;
> -
> -    status = RegistryOpenSubKey(NULL,
> -                                OldKeyName,
> -                                KEY_READ,
> -                                &OldKey);
> -    if (!NT_SUCCESS(status))
> -        goto fail5;
> -
> -    status = RegistryCreateSubKey(NULL,
> -                                  NewKeyName,
> -                                  REG_OPTION_NON_VOLATILE,
> -                                  &NewKey);
> -    if (!NT_SUCCESS(status))
> -        goto fail6;
> -
> -    status = RegistryEnumerateValues(OldKey,
> -                                     SettingsCopyInterfaceValue,
> -                                     NewKey);
> -    if (!NT_SUCCESS(status))
> -        goto fail7;
> -
> -    RegistryCloseKey(NewKey);
> -    RegistryCloseKey(OldKey);
> -    __SettingsFree(NewKeyName);
> -    __SettingsFree(OldKeyName);
> -
> -    return STATUS_SUCCESS;
> -
> -fail7:
> -    Error("fail7\n");
> -
> -    RegistryCloseKey(NewKey);
> -
> -fail6:
> -    Error("fail6\n");
> -
> -    RegistryCloseKey(OldKey);
> -
> -fail5:
> -    Error("fail5\n");
> -
> -fail4:
> -    Error("fail4\n");
> -
> -fail3:
> -    Error("fail3\n");
> -
> -    __SettingsFree(NewKeyName);
> -
> -fail2:
> -    Error("fail2\n");
> -
> -    __SettingsFree(OldKeyName);
> -
> -fail1:
> -    Error("fail1 (%08x)\n", status);
> -
> -    return status;
> -}
> -
> -static NTSTATUS
> -SettingsStoreCurrent(
> -    IN  HANDLE          SubKey,
> -    IN  PANSI_STRING    Guid,
> -    IN  PNET_LUID       Luid
> -    )
> -{
> -
> -    NTSTATUS            status;
> -
> -    status = RegistryUpdateSzValue(SubKey,
> -                                   "NetCfgInstanceId",
> -                                   REG_SZ,
> -                                   Guid);
> -    if (!NT_SUCCESS(status))
> -        goto fail1;
> -
> -    status = RegistryUpdateBinaryValue(SubKey,
> -                                       "NetLuid",
> -                                       Luid,
> -                                       sizeof(NET_LUID));
> -    if (!NT_SUCCESS(status))
> -        goto fail2;
> -
> -    (VOID) RegistryDeleteValue(SubKey,
> -                               "HasSettings");
> -
> -    return STATUS_SUCCESS;
> -
> -fail2:
> -    Error("fail2\n");
> -
> -fail1:
> -    Error("fail1 (%08x)\n", status);
> -
> -    return status;
> -}
> -
> -static NTSTATUS
> -SettingsCopy(
> -    IN  PCHAR           SubKeyName,
> -    IN  PANSI_STRING    OldGuid,
> -    IN  PNET_LUID       OldLuid,
> -    IN  PANSI_STRING    NewGuid,
> -    IN  PNET_LUID       NewLuid
> -     )
> -{
> -    HANDLE              SettingsKey;
> -    HANDLE              SubKey;
> -    NTSTATUS            status;
> -
> -    Trace("====>\n");
> -    Info("VIF/%s: FROM %Z\n", SubKeyName, OldGuid);
> -    Info("VIF/%s: TO   %Z\n", SubKeyName, NewGuid);
> -
> -    (VOID) SettingsCopyInterface(INTERFACES_PATH(NetBT),
> -                                 "Tcpip_",
> -                                 OldGuid,
> -                                 NewGuid);
> -
> -    (VOID) SettingsCopyInterface(INTERFACES_PATH(Tcpip),
> -                                 "",
> -                                 OldGuid,
> -                                 NewGuid);
> -
> -    (VOID) SettingsCopyInterface(INTERFACES_PATH(Tcpip6),
> -                                 "",
> -                                 OldGuid,
> -                                 NewGuid);
> -
> -    (VOID) SettingsCopyIpAddresses(4,
> -                                   OldLuid,
> -                                   NewLuid);
> -
> -    (VOID) SettingsCopyIpAddresses(6,
> -                                   OldLuid,
> -                                   NewLuid);
> -
> -    SettingsKey = DriverGetSettingsKey();
> -
> -    status = RegistryCreateSubKey(SettingsKey,
> -                                  SubKeyName,
> -                                  REG_OPTION_NON_VOLATILE,
> -                                  &SubKey);
> -    if (!NT_SUCCESS(status))
> -        goto fail1;
> -
> -    status = SettingsStoreCurrent(SubKey,
> -                                  NewGuid,
> -                                  NewLuid);
> -    if (!NT_SUCCESS(status))
> -        goto fail2;
> -
> -    RegistryCloseKey(SubKey);
> -
> -    Trace("<====\n");
> -
> -    return STATUS_SUCCESS;
> -
> -fail2:
> -    Error("fail2\n");
> -
> -    RegistryCloseKey(SubKey);
> -
> -fail1:
> -    Error("fail1 (%08x)\n", status);
> -
> -    return status;
> -}
> -
> -NTSTATUS
> -SettingsSave(
> -    IN  PCHAR       SubKeyName,
> -    IN  PWCHAR      Alias,
> -    IN  PWCHAR      Description,
> -    IN  LPGUID      InterfaceGuid,
> -    IN  PNET_LUID   InterfaceLuid
> -    )
> -{
> -    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);
> -    if (!NT_SUCCESS(status))
> -        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;
> -
> -    RtlFreeAnsiString(&Ansi);
> -
> -done:
> -    RegistryCloseKey(SubKey);
> -
> -    return STATUS_SUCCESS;
> -
> -fail3:
> -    Error("fail3\n");
> -
> -    RegistryCloseKey(SubKey);
> -
> -fail2:
> -    Error("fail2\n");
> -
> -    RtlFreeAnsiString(&Ansi);
> -
> -fail1:
> -    Error("fail1 (%08x)\n", status);
> -
> -    return status;
> -}
> -
> -NTSTATUS
> -SettingsRestore(
> -    IN  PCHAR       SubKeyName,
> -    IN  PWCHAR      Alias,
> -    IN  PWCHAR      Description,
> -    IN  LPGUID      InterfaceGuid,
> -    IN  PNET_LUID   InterfaceLuid
> -    )
> -{
> -    HANDLE          SettingsKey;
> -    HANDLE          SubKey;
> -    ANSI_STRING     Ansi;
> -    PANSI_STRING    NetCfgInstanceId;
> -    PNET_LUID       NetLuid;
> -    ULONG           NetLuidLength;
> -    NTSTATUS        status;
> -
> -    SettingsKey = DriverGetSettingsKey();
> -
> -    status = RegistryOpenSubKey(SettingsKey,
> -                                SubKeyName,
> -                                KEY_READ,
> -                                &SubKey);
> -    if (!NT_SUCCESS(status))
> -        goto fail1;
> -
> -    status = RegistryQuerySzValue(SubKey,
> -                                  "NetCfgInstanceId",
> -                                  NULL,
> -                                  &NetCfgInstanceId);
> -    if (!NT_SUCCESS(status))
> -        goto fail2;
> -
> -    NetLuidLength = 0;
> -    status = RegistryQueryBinaryValue(SubKey,
> -                                      "NetLuid",
> -                                      &NetLuid,
> -                                      &NetLuidLength);
> -    if (!NT_SUCCESS(status))
> -        goto fail3;
> -
> -    status = __GuidToString(InterfaceGuid, &Ansi);
> -    if (!NT_SUCCESS(status))
> -        goto fail4;
> -
> -    if (RtlCompareString(NetCfgInstanceId, &Ansi, TRUE) != 0) {
> -        Info("TO %ws (%ws)\n", Alias, Description);
> -        Info("TO %Z\n", Ansi);
> -        Info("TO %016llx\n", InterfaceLuid->Value);
> -
> -        SettingsCopy(SubKeyName,
> -                     NetCfgInstanceId,
> -                     NetLuid,
> -                     &Ansi,
> -                     InterfaceLuid);
> -    } else {
> -        Info("%s: SettingsCopy not required for %ws\n",
> -             SubKeyName,
> -             Description);
> -    }
> -
> -    RtlFreeAnsiString(&Ansi);
> -
> -    if (NetLuidLength != 0)
> -        RegistryFreeBinaryValue(NetLuid);
> -
> -    RegistryFreeSzValue(NetCfgInstanceId);
> -
> -    RegistryCloseKey(SubKey);
> -
> -    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 (%08x)\n", status);
> -
> -    return status;
> -}
> diff --git a/src/xenvif/settings.h b/src/xenvif/settings.h
> deleted file mode 100644
> index 3f964bb..0000000
> --- a/src/xenvif/settings.h
> +++ /dev/null
> @@ -1,54 +0,0 @@
> -/* Copyright (c) Xen Project.
> - * Copyright (c) Cloud Software Group, 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  PCHAR       SubKeyName,
> -    IN  PWCHAR      Alias,
> -    IN  PWCHAR      Description,
> -    IN  LPGUID      InterfaceGuid,
> -    IN  PNET_LUID   InterfaceLuid
> -    );
> -
> -extern NTSTATUS
> -SettingsRestore(
> -    IN  PCHAR       SubKeyName,
> -    IN  PWCHAR      Alias,
> -    IN  PWCHAR      Description,
> -    IN  LPGUID      InterfaceGuid,
> -    IN  PNET_LUID   InterfaceLuid
> -    );
> -
> -#endif  // _XENVIF_SETTINGS_H
> diff --git a/vs2019/xenvif/xenvif.vcxproj b/vs2019/xenvif/xenvif.vcxproj
> index 0412426..3e48cf7 100644
> --- a/vs2019/xenvif/xenvif.vcxproj
> +++ b/vs2019/xenvif/xenvif.vcxproj
> @@ -82,7 +82,6 @@
>       <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/vs2022/xenvif/xenvif.vcxproj b/vs2022/xenvif/xenvif.vcxproj
> index be84232..af9fe96 100644
> --- a/vs2022/xenvif/xenvif.vcxproj
> +++ b/vs2022/xenvif/xenvif.vcxproj
> @@ -74,7 +74,6 @@
>       <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" />



 


Rackspace

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