[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 2/2] Rework network settings copy code.
Rather than copying network settings twice (once on save and once on restore), stash the current network interface guid and network Luid on save and copy settings from the previous to the new location on restore. By relying on the current settings, the copy code will always restore the settings that are current. This will pick up any changes that are made without requiring a copy from the save. Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> --- src/xenvif/pdo.c | 93 +++-- src/xenvif/settings.c | 810 +++++++++++++++++++++++------------------- 2 files changed, 508 insertions(+), 395 deletions(-) diff --git a/src/xenvif/pdo.c b/src/xenvif/pdo.c index b3a4aae..82775b4 100644 --- a/src/xenvif/pdo.c +++ b/src/xenvif/pdo.c @@ -1180,6 +1180,45 @@ fail1: return status; } +static NTSTATUS +PdoGetInterfaceLuid( + IN PXENVIF_PDO Pdo, + IN HANDLE Key, + OUT PNET_LUID Luid + ) +{ + ULONG Value; + NTSTATUS status; + + UNREFERENCED_PARAMETER(Pdo); + + status = RegistryQueryDwordValue(Key, + "*IfType", + &Value); + if (!NT_SUCCESS(status)) + goto fail1; + + Luid->Info.IfType = Value; + + status = RegistryQueryDwordValue(Key, + "NetLuidIndex", + &Value); + if (!NT_SUCCESS(status)) + goto fail2; + + Luid->Info.NetLuidIndex = Value; + + return STATUS_SUCCESS; + +fail2: + Error("fail2\n"); + +fail1: + Error("fail1 (%08x)\n", status); + + return status; +} + static VOID PdoUnplugRequest( IN PXENVIF_PDO Pdo, @@ -1216,7 +1255,6 @@ PdoStartDevice( PIO_STACK_LOCATION StackLocation; HANDLE SoftwareKey; HANDLE HardwareKey; - ULONG HasSettings; GUID Guid; NTSTATUS status; @@ -1307,39 +1345,44 @@ PdoStartDevice( goto fail9; } - status = RegistryQueryDwordValue(SoftwareKey, - "HasSettings", - &HasSettings); - if (!NT_SUCCESS(status)) - HasSettings = 0; - - if (HasSettings == 0) { - // - // If there is a stack bound then restore any settings that - // may have been saved from an aliasing emulated device. - // - status = PdoGetInterfaceGuid(Pdo, SoftwareKey, &Guid); + // + // If there is a stack bound then restore any settings that + // may have been saved from an aliasing emulated device. + // + status = PdoGetInterfaceGuid(Pdo, SoftwareKey, &Guid); + if (NT_SUCCESS(status)) { + NET_LUID NetLuid; + PWCHAR Alias; + PWCHAR Description; + + RtlZeroMemory(&NetLuid, sizeof(NET_LUID)); + Alias = NULL; + Description = NULL; + + status = PdoGetInterfaceLuid(Pdo, SoftwareKey, &NetLuid); if (NT_SUCCESS(status)) { for (Index = 0; Index < Table->NumEntries; Index++) { PMIB_IF_ROW2 Row = &Table->Table[Index]; - if (!IsEqualGUID(&Row->InterfaceGuid, &Guid)) + Trace("%s: CHECKING %ws (%ws)\n", + __PdoGetName(Pdo), + Row->Alias, + Row->Description); + + if (Row->InterfaceLuid.Value != NetLuid.Value) continue; - (VOID) SettingsRestore(__PdoGetName(Pdo), - Row->Alias, - Row->Description, - &Row->InterfaceGuid, - &Row->InterfaceLuid); + Alias = Row->Alias; + Description = Row->Description; break; } - - HasSettings = 1; - - (VOID) RegistryUpdateDwordValue(SoftwareKey, - "HasSettings", - HasSettings); } + + (VOID) SettingsRestore(__PdoGetName(Pdo), + Alias, + Description, + &Guid, + &NetLuid); } StackLocation = IoGetCurrentIrpStackLocation(Irp); diff --git a/src/xenvif/settings.c b/src/xenvif/settings.c index 214248b..7f9a14b 100644 --- a/src/xenvif/settings.c +++ b/src/xenvif/settings.c @@ -40,6 +40,12 @@ #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" + static FORCEINLINE PVOID __SettingsAllocate( IN ULONG Length @@ -56,482 +62,444 @@ __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 +static FORCEINLINE NTSTATUS +__GuidToString( + IN LPGUID Guid, + OUT PANSI_STRING Ansi ) { - PSETTINGS_INTERFACE_COPY_PARAMETERS Parameters = Context; - NTSTATUS status; + NTSTATUS status; + UNICODE_STRING Unicode; - Trace("%s:%Z\n", Parameters->SaveKeyName, ValueName); + status = RtlStringFromGUID(Guid, &Unicode); + if (!NT_SUCCESS(status)) + goto fail1; - switch (Type) { - case REG_DWORD: { - ULONG Value; + status = RtlUnicodeStringToAnsiString(Ansi, &Unicode, TRUE); + if (!NT_SUCCESS(status)) + goto fail2; - status = RegistryQueryDwordValue(SourceKey, - ValueName->Buffer, - &Value); - if (NT_SUCCESS(status)) - (VOID) RegistryUpdateDwordValue(Parameters->DestinationKey, - ValueName->Buffer, - Value); + RtlFreeUnicodeString(&Unicode); - break; - } - case REG_SZ: - case REG_MULTI_SZ: { - PANSI_STRING Value; + return STATUS_SUCCESS; - status = RegistryQuerySzValue(SourceKey, - ValueName->Buffer, - NULL, - &Value); - if (NT_SUCCESS(status)) { - (VOID) RegistryUpdateSzValue(Parameters->DestinationKey, - ValueName->Buffer, - Type, - Value); - RegistryFreeSzValue(Value); - } +fail2: + Error("fail2\n"); - 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); - } + RtlFreeUnicodeString(&Unicode); - return STATUS_SUCCESS; +fail1: + Error("fail1 (%08x)\n", status); + + return status; } +typedef struct _SETTINGS_COPY_IP_ADDRESS_PARAMETERS { + PCHAR SrcPrefix; + PCHAR DstPrefix; +} SETTINGS_COPY_IP_ADDRESS_PARAMETERS, *PSETTINGS_COPY_IP_ADDRESS_PARAMETERS; + static NTSTATUS -SettingsCopyInterface( - IN HANDLE SettingsKey, - IN PCHAR SaveKeyName, - IN PCHAR InterfacesPath, - IN PCHAR InterfacePrefix, - IN LPGUID Guid, - IN BOOLEAN Save +SettingsCopyIpAddressesValue( + 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; - - Trace("====>\n"); - - status = RtlStringFromGUID(Guid, &Unicode); - if (!NT_SUCCESS(status)) - goto fail1; + PSETTINGS_COPY_IP_ADDRESS_PARAMETERS Parameters = Context; + ULONG Length; + PVOID Value; + ULONG ValueLength; + NTSTATUS status; - Length = (ULONG)(((Unicode.Length / sizeof (WCHAR)) + - 1) * sizeof (CHAR)); + UNREFERENCED_PARAMETER(Type); - InterfaceName = __SettingsAllocate(Length); + Length = (ULONG)strlen(Parameters->SrcPrefix); - status = STATUS_NO_MEMORY; - if (InterfaceName == NULL) - goto fail2; + if (_strnicmp(ValueName->Buffer, + Parameters->SrcPrefix, + Length) != 0) + goto done; - status = RtlStringCbPrintfA(InterfaceName, - Length, - "%wZ", - &Unicode); - ASSERT(NT_SUCCESS(status)); + Trace(" -> %Z\n", ValueName); - status = RegistryOpenSubKey(NULL, - InterfacesPath, - KEY_ALL_ACCESS, - &InterfacesKey); + status = RegistryQueryBinaryValue(Key, + ValueName->Buffer, + &Value, + &ValueLength); 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; + goto fail1; - status = RtlStringCbPrintfA(KeyName, - Length, - "%s%s", - InterfacePrefix, - InterfaceName); - ASSERT(NT_SUCCESS(status)); - - status = (!Save) ? - RegistryCreateSubKey(InterfacesKey, - KeyName, - REG_OPTION_NON_VOLATILE, - &Key) : - RegistryOpenSubKey(InterfacesKey, - KeyName, - KEY_READ, - &Key); + status = RegistryDeleteValue(Key, + ValueName->Buffer); if (!NT_SUCCESS(status)) - goto fail5; + goto fail2; - status = (Save) ? - RegistryCreateSubKey(SettingsKey, - SaveKeyName, - REG_OPTION_NON_VOLATILE, - &SaveKey) : - RegistryOpenSubKey(SettingsKey, - SaveKeyName, - KEY_READ, - &SaveKey); - if (!NT_SUCCESS(status)) - goto fail6; + ASSERT(Length < ValueName->Length); + memcpy(ValueName->Buffer, Parameters->DstPrefix, Length); - if (Save) { - SETTINGS_INTERFACE_COPY_PARAMETERS Parameters; + Trace(" <- %Z\n", ValueName); - Parameters.SaveKeyName = SaveKeyName; - Parameters.DestinationKey = SaveKey; + status = RegistryUpdateBinaryValue(Key, + ValueName->Buffer, + Value, + ValueLength); + if (!NT_SUCCESS(status)) + goto fail3; - status = RegistryEnumerateValues(Key, - SettingsCopyInterfaceValue, - &Parameters); - } else { // Restore - SETTINGS_INTERFACE_COPY_PARAMETERS Parameters; + if (ValueLength != 0) + RegistryFreeBinaryValue(Value); - Parameters.SaveKeyName = SaveKeyName; - Parameters.DestinationKey = Key; +done: + return STATUS_SUCCESS; - status = RegistryEnumerateValues(SaveKey, - SettingsCopyInterfaceValue, - &Parameters); - } +fail3: + Error("fail3\n"); - if (!NT_SUCCESS(status)) - goto fail7; +fail2: + Error("fail2\n"); - RegistryCloseKey(SaveKey); + if (ValueLength != 0) + RegistryFreeBinaryValue(Value); - RegistryCloseKey(Key); +fail1: + Error("fail1 (%08x)\n", status); - __SettingsFree(KeyName); + return status; +} - RegistryCloseKey(InterfacesKey); +static NTSTATUS +SettingsCopyIpAddresses( + IN ULONG Version, + IN PNET_LUID OldLuid, + IN PNET_LUID NewLuid + ) +{ + PCHAR Path; + CHAR SrcPrefix[17]; + CHAR DstPrefix[17]; + SETTINGS_COPY_IP_ADDRESS_PARAMETERS Parameters; + HANDLE Key; + NTSTATUS status; - __SettingsFree(InterfaceName); + Path = Version == 4 ? IPV4_PATH : IPV6_PATH; - RtlFreeUnicodeString(&Unicode); + status = RtlStringCbPrintfA(SrcPrefix, + sizeof(SrcPrefix), + "%16llx", + _byteswap_uint64(OldLuid->Value)); + if (!NT_SUCCESS(status)) + goto fail1; - Trace("<====\n"); + status = RtlStringCbPrintfA(DstPrefix, + sizeof(DstPrefix), + "%16llx", + _byteswap_uint64(NewLuid->Value)); + if (!NT_SUCCESS(status)) + goto fail2; - return STATUS_SUCCESS; + status = RegistryOpenSubKey(NULL, + Path, + KEY_ALL_ACCESS, + &Key); + if (!NT_SUCCESS(status)) + goto fail3; -fail7: - Error("fail7\n"); + Info("IPv%u: %s -> %s\n", Version, SrcPrefix, DstPrefix); - RegistryCloseKey(SaveKey); + Parameters.SrcPrefix = SrcPrefix; + Parameters.DstPrefix = DstPrefix; -fail6: - Error("fail6\n"); + status = RegistryEnumerateValues(Key, + SettingsCopyIpAddressesValue, + &Parameters); + if (!NT_SUCCESS(status)) + goto fail4; RegistryCloseKey(Key); -fail5: - Error("fail5\n"); - - __SettingsFree(KeyName); + return STATUS_SUCCESS; fail4: Error("fail4\n"); - RegistryCloseKey(InterfacesKey); + RegistryCloseKey(Key); 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 +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 -SettingsCopyIpAddressesValue( - IN PVOID Context, - IN HANDLE SourceKey, - IN PANSI_STRING SourceValueName, - IN ULONG Type +SettingsCopyInterface( + IN PCHAR InterfacePath, + IN PCHAR InterfacePrefix, + IN PANSI_STRING OldGuid, + IN PANSI_STRING NewGuid ) { - PSETTINGS_IP_ADDRESSES_COPY_PARAMETERS Parameters = Context; - ULONG SourceValuePrefixLength; - ULONG DestinationValuePrefixLength; - ULONG DestinationValueNameLength; - PCHAR DestinationValueName; - PVOID Value; - ULONG ValueLength; - NTSTATUS status; + 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); - if (Type != REG_BINARY) - goto done; + status = STATUS_NO_MEMORY; + OldKeyName = __SettingsAllocate(OldKeyLength); + if (OldKeyName == NULL) + goto fail1; - SourceValuePrefixLength = (ULONG)strlen(Parameters->SourceValuePrefix); - DestinationValuePrefixLength = (ULONG)strlen(Parameters->DestinationValuePrefix); + NewKeyName = __SettingsAllocate(NewKeyLength); + if (NewKeyName == NULL) + goto fail2; - if (_strnicmp(SourceValueName->Buffer, - Parameters->SourceValuePrefix, - SourceValuePrefixLength) != 0) - goto done; + status = RtlStringCbPrintfA(OldKeyName, + OldKeyLength, + "%s%s%Z", + InterfacePath, + InterfacePrefix, + OldGuid); + if (!NT_SUCCESS(status)) + goto fail3; - DestinationValueNameLength = SourceValueName->Length - - (SourceValuePrefixLength * sizeof (CHAR)) + - ((DestinationValuePrefixLength + 1) * sizeof (CHAR)); + status = RtlStringCbPrintfA(NewKeyName, + NewKeyLength, + "%s%s%Z", + InterfacePath, + InterfacePrefix, + NewGuid); + if (!NT_SUCCESS(status)) + goto fail4; - DestinationValueName = __SettingsAllocate(DestinationValueNameLength); + status = RegistryOpenSubKey(NULL, + OldKeyName, + KEY_READ, + &OldKey); + if (!NT_SUCCESS(status)) + goto fail5; - status = STATUS_NO_MEMORY; - if (DestinationValueName == NULL) - goto fail1; + status = RegistryCreateSubKey(NULL, + NewKeyName, + REG_OPTION_NON_VOLATILE, + &NewKey); + if (!NT_SUCCESS(status)) + goto fail6; - status = RtlStringCbPrintfA(DestinationValueName, - DestinationValueNameLength, - "%s%s", - Parameters->DestinationValuePrefix, - SourceValueName->Buffer + SourceValuePrefixLength); - ASSERT(NT_SUCCESS(status)); + status = RegistryEnumerateValues(OldKey, + SettingsCopyInterfaceValue, + NewKey); + if (!NT_SUCCESS(status)) + goto fail7; - Trace("Version%u: %Z -> %s\n", - Parameters->Version, - SourceValueName, - DestinationValueName); + RegistryCloseKey(NewKey); + RegistryCloseKey(OldKey); + __SettingsFree(NewKeyName); + __SettingsFree(OldKeyName); - status = RegistryQueryBinaryValue(SourceKey, - SourceValueName->Buffer, - &Value, - &ValueLength); - if (NT_SUCCESS(status)) { - (VOID) RegistryUpdateBinaryValue(Parameters->DestinationKey, - DestinationValueName, - Value, - ValueLength); - RegistryFreeBinaryValue(Value); - } + return STATUS_SUCCESS; - __SettingsFree(DestinationValueName); +fail7: + Error("fail7\n"); -done: - return STATUS_SUCCESS; + RegistryCloseKey(NewKey); -fail1: - Error("fail1 (%08x)\n", status); +fail6: + Error("fail6\n"); - return status; -} + RegistryCloseKey(OldKey); -#define IPV6_PATH "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Nsi\\{eb004a01-9b1a-11d4-9123-0050047759bc}\\10" +fail5: + Error("fail5\n"); -#define IPV4_PATH "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Nsi\\{eb004a00-9b1a-11d4-9123-0050047759bc}\\10" +fail4: + Error("fail4\n"); -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; +fail3: + Error("fail3\n"); - Trace("====>\n"); + __SettingsFree(NewKeyName); - ASSERT(Version == 4 || Version == 6); - Path = (Version == 4) ? IPV4_PATH : IPV6_PATH; +fail2: + Error("fail2\n"); - 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; - } + __SettingsFree(OldKeyName); - ValuePrefixLength = (ULONG)(((sizeof (NET_LUID) * 2) + - 1) * sizeof (CHAR)); +fail1: + Error("fail1 %08x\n", status); - ValuePrefix = __SettingsAllocate(ValuePrefixLength); + return status; +} - status = STATUS_NO_MEMORY; - if (ValuePrefix == NULL) - goto fail1; +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; - 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; + Info("VIF/%s: FROM %Z\n", SubKeyName, OldGuid); + Info("VIF/%s: TO %Z\n", SubKeyName, NewGuid); - if (Save) { - SETTINGS_IP_ADDRESSES_COPY_PARAMETERS Parameters; + (VOID) SettingsCopyInterface(INTERFACES_PATH(TCPIP), + "", + OldGuid, + NewGuid); - Parameters.Version = Version; - Parameters.SourceValuePrefix = ValuePrefix; - Parameters.DestinationKey = SaveKey; - Parameters.DestinationValuePrefix = "LUID"; + (VOID) SettingsCopyInterface(INTERFACES_PATH(TCPIP6), + "", + OldGuid, + NewGuid); - status = RegistryEnumerateValues(Key, - SettingsCopyIpAddressesValue, - &Parameters); - } else { // Restore - SETTINGS_IP_ADDRESSES_COPY_PARAMETERS Parameters; + (VOID) SettingsCopyInterface(INTERFACES_PATH(NETBT), + "Tcpip_", + OldGuid, + NewGuid); - Parameters.Version = Version; - Parameters.SourceValuePrefix = "LUID"; - Parameters.DestinationKey = Key; - Parameters.DestinationValuePrefix = ValuePrefix; + (VOID) SettingsCopyIpAddresses(4, + OldLuid, + NewLuid); - status = RegistryEnumerateValues(SaveKey, - SettingsCopyIpAddressesValue, - &Parameters); - } + (VOID) SettingsCopyIpAddresses(6, + OldLuid, + NewLuid); - RegistryCloseKey(SaveKey); + SettingsKey = DriverGetSettingsKey(); - __SettingsFree(ValuePrefix); + status = RegistryCreateSubKey(SettingsKey, + SubKeyName, + REG_OPTION_NON_VOLATILE, + &SubKey); + if (!NT_SUCCESS(status)) + goto fail1; - RegistryCloseKey(Key); + status = RegistryUpdateSzValue(SubKey, + "NetCfgInstanceId", + REG_SZ, + NewGuid); + if (!NT_SUCCESS(status)) + goto fail2; -done: - Trace("<====\n"); + status = RegistryUpdateBinaryValue(SubKey, + "NetLuid", + NewLuid, + sizeof(NET_LUID)); + if (!NT_SUCCESS(status)) + goto fail3; + + RegistryCloseKey(SubKey); return STATUS_SUCCESS; +fail3: + Error("fail3\n"); + fail2: Error("fail2\n"); - __SettingsFree(ValuePrefix); + RegistryCloseKey(SubKey); fail1: Error("fail1 (%08x)\n", status); - RegistryCloseKey(Key); - return status; } -#define INTERFACES_PATH(_Name) "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\" ## #_Name ## "\\Parameters\\Interfaces\\" - -static VOID -SettingsCopy( - IN HANDLE SettingsKey, - IN LPGUID InterfaceGuid, - IN PNET_LUID InterfaceLuid, - IN BOOLEAN Save - ) -{ - Trace("====>\n"); - - (VOID) SettingsCopyInterface(SettingsKey, - "NetBT", - INTERFACES_PATH(NetBT), - "Tcpip_", - InterfaceGuid, - Save); - - (VOID) SettingsCopyInterface(SettingsKey, - "Tcpip", - INTERFACES_PATH(Tcpip), - "", - InterfaceGuid, - Save); - - (VOID) SettingsCopyInterface(SettingsKey, - "Tcpip6", - INTERFACES_PATH(Tcpip6), - "", - InterfaceGuid, - Save); - - (VOID) SettingsCopyIpAddresses(SettingsKey, - 4, - InterfaceLuid, - Save); - - (VOID) SettingsCopyIpAddresses(SettingsKey, - 6, - InterfaceLuid, - Save); - - Trace("<====\n"); -} - NTSTATUS SettingsSave( IN PCHAR SubKeyName, @@ -543,6 +511,8 @@ SettingsSave( { HANDLE SettingsKey; HANDLE SubKey; + ANSI_STRING Ansi; + ULONG HasSettings; NTSTATUS status; Info("FROM %ws (%ws)\n", Alias, Description); @@ -556,12 +526,59 @@ SettingsSave( if (!NT_SUCCESS(status)) goto fail1; - SettingsCopy(SubKey, InterfaceGuid, InterfaceLuid, TRUE); + HasSettings = 0; + status = RegistryQueryDwordValue(SubKey, + "HasSettings", + &HasSettings); + if (!NT_SUCCESS(status)) + HasSettings = 0; + + if (HasSettings != 0) + goto done; + + status = __GuidToString(InterfaceGuid, &Ansi); + if (!NT_SUCCESS(status)) + goto fail2; + + Info("FROM %Z\n", Ansi); + + status = RegistryUpdateSzValue(SubKey, + "NetCfgInstanceId", + REG_SZ, + &Ansi); + if (!NT_SUCCESS(status)) + goto fail3; + + status = RegistryUpdateBinaryValue(SubKey, + "NetLuid", + InterfaceLuid, + sizeof(NET_LUID)); + if (!NT_SUCCESS(status)) + goto fail4; + + RtlFreeAnsiString(&Ansi); + +done: + (VOID) RegistryDeleteValue(SubKey, + "HasSettings"); RegistryCloseKey(SubKey); return STATUS_SUCCESS; +fail4: + Error("fail4\n"); + +fail3: + Error("fail3\n"); + + RtlFreeAnsiString(&Ansi); + +fail2: + Error("fail2\n"); + + RegistryCloseKey(SubKey); + fail1: Error("fail1\n", status); @@ -579,6 +596,10 @@ SettingsRestore( { HANDLE SettingsKey; HANDLE SubKey; + ANSI_STRING Ansi; + PANSI_STRING NetCfgInstanceId; + PNET_LUID NetLuid; + ULONG NetLuidLength; NTSTATUS status; SettingsKey = DriverGetSettingsKey(); @@ -594,15 +615,64 @@ SettingsRestore( goto fail1; } - Info("TO %ws (%ws)\n", Alias, Description); + status = RegistryQuerySzValue(SubKey, + "NetCfgInstanceId", + NULL, + &NetCfgInstanceId); + if (!NT_SUCCESS(status)) + goto fail2; + + NetLuidLength = 0; + status = RegistryQueryBinaryValue(SubKey, + "NetLuid", + &NetLuid, + &NetLuidLength); + if (!NT_SUCCESS(status)) + goto fail3; + + status = __GuidToString(InterfaceGuid, &Ansi); + if (!NT_SUCCESS(status)) + goto fail4; + + if (RtlCompareString(NetCfgInstanceId, &Ansi, TRUE) != 0) { + Info("TO %ws (%ws)\n", Alias, Description); + Info("TO %Z\n", Ansi); + + SettingsCopy(SubKeyName, + NetCfgInstanceId, + NetLuid, + &Ansi, + InterfaceLuid); + } + + RtlFreeAnsiString(&Ansi); + + if (NetLuidLength != 0) + RegistryFreeBinaryValue(NetLuid); - SettingsCopy(SubKey, InterfaceGuid, InterfaceLuid, FALSE); + RegistryFreeSzValue(NetCfgInstanceId); RegistryCloseKey(SubKey); done: return STATUS_SUCCESS; +fail4: + Error("fail4\n"); + + if (NetLuidLength != 0) + RegistryFreeBinaryValue(NetLuid); + +fail3: + Error("fail3\n"); + + RegistryFreeSzValue(NetCfgInstanceId); + +fail2: + Error("fail2\n"); + + RegistryCloseKey(SubKey); + fail1: Error("fail1\n", status); -- 2.32.0.windows.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |