[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |