[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 Guid and Luid 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 | 98 ++++-- src/xenvif/settings.c | 728 +++++++++++++++++++++++------------------- 2 files changed, 479 insertions(+), 347 deletions(-) diff --git a/src/xenvif/pdo.c b/src/xenvif/pdo.c index b3a4aae..4a6bfd1 100644 --- a/src/xenvif/pdo.c +++ b/src/xenvif/pdo.c @@ -1180,6 +1180,49 @@ fail1: return status; } +static NTSTATUS +PdoGetInterfaceLuid( + IN PXENVIF_PDO Pdo, + IN HANDLE Key, + OUT PNET_LUID Luid + ) +{ + ULONG Value; + NTSTATUS status; + + UNREFERENCED_PARAMETER(Pdo); + + Luid->Value = 0ull; + + 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); + + Luid->Value = 0ull; + + return status; +} + static VOID PdoUnplugRequest( IN PXENVIF_PDO Pdo, @@ -1216,7 +1259,6 @@ PdoStartDevice( PIO_STACK_LOCATION StackLocation; HANDLE SoftwareKey; HANDLE HardwareKey; - ULONG HasSettings; GUID Guid; NTSTATUS status; @@ -1307,39 +1349,45 @@ 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 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]; - if (!IsEqualGUID(&Row->InterfaceGuid, &Guid)) + Trace("%s: CHECKING %ws (%ws)\n", + __PdoGetName(Pdo), + Row->Alias, + Row->Description); + + if (Row->InterfaceLuid.Value != Luid.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, + &Luid); } StackLocation = IoGetCurrentIrpStackLocation(Irp); diff --git a/src/xenvif/settings.c b/src/xenvif/settings.c index 214248b..7483ff3 100644 --- a/src/xenvif/settings.c +++ b/src/xenvif/settings.c @@ -40,6 +40,22 @@ #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 @@ -56,23 +72,181 @@ __SettingsFree( __FreePoolWithTag(Buffer, SETTINGS_TAG); } -typedef struct _SETTINGS_INTERFACE_COPY_PARAMETERS { - PCHAR SaveKeyName; - HANDLE DestinationKey; -} SETTINGS_INTERFACE_COPY_PARAMETERS, *PSETTINGS_INTERFACE_COPY_PARAMETERS; +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 -SettingsCopyInterfaceValue( - IN PVOID Context, - IN HANDLE SourceKey, - IN PANSI_STRING ValueName, - IN ULONG Type +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 ) { - PSETTINGS_INTERFACE_COPY_PARAMETERS Parameters = Context; + SETTINGS_COPY_IP_ADDRESS_PARAMETERS Parameters; + HANDLE Key; NTSTATUS status; - Trace("%s:%Z\n", Parameters->SaveKeyName, ValueName); + 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: { @@ -82,7 +256,7 @@ SettingsCopyInterfaceValue( ValueName->Buffer, &Value); if (NT_SUCCESS(status)) - (VOID) RegistryUpdateDwordValue(Parameters->DestinationKey, + (VOID) RegistryUpdateDwordValue(DestinationKey, ValueName->Buffer, Value); @@ -97,7 +271,7 @@ SettingsCopyInterfaceValue( NULL, &Value); if (NT_SUCCESS(status)) { - (VOID) RegistryUpdateSzValue(Parameters->DestinationKey, + (VOID) RegistryUpdateSzValue(DestinationKey, ValueName->Buffer, Type, Value); @@ -115,7 +289,7 @@ SettingsCopyInterfaceValue( &Value, &Length); if (NT_SUCCESS(status)) { - (VOID) RegistryUpdateBinaryValue(Parameters->DestinationKey, + (VOID) RegistryUpdateBinaryValue(DestinationKey, ValueName->Buffer, Value, Length); @@ -134,160 +308,108 @@ SettingsCopyInterfaceValue( static NTSTATUS SettingsCopyInterface( - IN HANDLE SettingsKey, - IN PCHAR SaveKeyName, - IN PCHAR InterfacesPath, - IN PCHAR InterfacePrefix, - IN LPGUID Guid, - IN BOOLEAN Save + IN PCHAR InterfacePath, + IN PCHAR InterfacePrefix, + IN PANSI_STRING OldGuid, + IN PANSI_STRING NewGuid ) { - UNICODE_STRING Unicode; - ULONG Length; - PCHAR InterfaceName; - HANDLE InterfacesKey; - PCHAR KeyName; - HANDLE Key; - HANDLE SaveKey; - NTSTATUS status; - - Trace("====>\n"); + 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 = RtlStringFromGUID(Guid, &Unicode); - if (!NT_SUCCESS(status)) + status = STATUS_NO_MEMORY; + OldKeyName = __SettingsAllocate(OldKeyLength); + if (OldKeyName == NULL) goto fail1; - Length = (ULONG)(((Unicode.Length / sizeof (WCHAR)) + - 1) * sizeof (CHAR)); - - InterfaceName = __SettingsAllocate(Length); - - status = STATUS_NO_MEMORY; - if (InterfaceName == NULL) + NewKeyName = __SettingsAllocate(NewKeyLength); + if (NewKeyName == NULL) goto fail2; - status = RtlStringCbPrintfA(InterfaceName, - Length, - "%wZ", - &Unicode); - ASSERT(NT_SUCCESS(status)); - - status = RegistryOpenSubKey(NULL, - InterfacesPath, - KEY_ALL_ACCESS, - &InterfacesKey); + status = RtlStringCbPrintfA(OldKeyName, + OldKeyLength, + "%s%s%Z", + InterfacePath, + InterfacePrefix, + OldGuid); 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) + status = RtlStringCbPrintfA(NewKeyName, + NewKeyLength, + "%s%s%Z", + InterfacePath, + InterfacePrefix, + NewGuid); + if (!NT_SUCCESS(status)) 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); + status = RegistryOpenSubKey(NULL, + OldKeyName, + KEY_READ, + &OldKey); if (!NT_SUCCESS(status)) goto fail5; - status = (Save) ? - RegistryCreateSubKey(SettingsKey, - SaveKeyName, - REG_OPTION_NON_VOLATILE, - &SaveKey) : - RegistryOpenSubKey(SettingsKey, - SaveKeyName, - KEY_READ, - &SaveKey); + status = RegistryCreateSubKey(NULL, + NewKeyName, + REG_OPTION_NON_VOLATILE, + &NewKey); 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); - } - + status = RegistryEnumerateValues(OldKey, + SettingsCopyInterfaceValue, + NewKey); if (!NT_SUCCESS(status)) goto fail7; - RegistryCloseKey(SaveKey); - - RegistryCloseKey(Key); - - __SettingsFree(KeyName); - - RegistryCloseKey(InterfacesKey); - - __SettingsFree(InterfaceName); - - RtlFreeUnicodeString(&Unicode); - - Trace("<====\n"); + RegistryCloseKey(NewKey); + RegistryCloseKey(OldKey); + __SettingsFree(NewKeyName); + __SettingsFree(OldKeyName); return STATUS_SUCCESS; fail7: Error("fail7\n"); - RegistryCloseKey(SaveKey); + RegistryCloseKey(NewKey); fail6: Error("fail6\n"); - RegistryCloseKey(Key); + RegistryCloseKey(OldKey); fail5: Error("fail5\n"); - __SettingsFree(KeyName); - fail4: Error("fail4\n"); - RegistryCloseKey(InterfacesKey); - fail3: Error("fail3\n"); - __SettingsFree(InterfaceName); + __SettingsFree(NewKeyName); fail2: Error("fail2\n"); - RtlFreeUnicodeString(&Unicode); + __SettingsFree(OldKeyName); fail1: Error("fail1 (%08x)\n", status); @@ -295,180 +417,101 @@ 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; - static NTSTATUS -SettingsCopyIpAddressesValue( - IN PVOID Context, - IN HANDLE SourceKey, - IN PANSI_STRING SourceValueName, - IN ULONG Type +SettingsStoreCurrent( + IN HANDLE SubKey, + IN PANSI_STRING Guid, + IN PNET_LUID Luid ) { - 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); + NTSTATUS status; - status = STATUS_NO_MEMORY; - if (DestinationValueName == NULL) + status = RegistryUpdateSzValue(SubKey, + "NetCfgInstanceId", + REG_SZ, + Guid); + if (!NT_SUCCESS(status)) 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); - } + status = RegistryUpdateBinaryValue(SubKey, + "NetLuid", + Luid, + sizeof(NET_LUID)); + if (!NT_SUCCESS(status)) + goto fail2; - __SettingsFree(DestinationValueName); + (VOID) RegistryDeleteValue(SubKey, + "HasSettings"); -done: return STATUS_SUCCESS; +fail2: + Error("fail2\n"); + 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 - ) +SettingsCopy( + IN PCHAR SubKeyName, + IN PANSI_STRING OldGuid, + IN PNET_LUID OldLuid, + IN PANSI_STRING NewGuid, + IN PNET_LUID NewLuid + ) { - const CHAR *Path; - HANDLE Key; - ULONG ValuePrefixLength; - PCHAR ValuePrefix; - const CHAR *SaveKeyName; - HANDLE SaveKey; - NTSTATUS status; + HANDLE SettingsKey; + HANDLE SubKey; + NTSTATUS status; Trace("====>\n"); + Info("VIF/%s: FROM %Z\n", SubKeyName, OldGuid); + Info("VIF/%s: TO %Z\n", SubKeyName, NewGuid); - ASSERT(Version == 4 || Version == 6); - Path = (Version == 4) ? IPV4_PATH : IPV6_PATH; + (VOID) SettingsCopyInterface(INTERFACES_PATH(NetBT), + "Tcpip_", + OldGuid, + NewGuid); - 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; - } + (VOID) SettingsCopyInterface(INTERFACES_PATH(Tcpip), + "", + OldGuid, + NewGuid); - ValuePrefixLength = (ULONG)(((sizeof (NET_LUID) * 2) + - 1) * sizeof (CHAR)); + (VOID) SettingsCopyInterface(INTERFACES_PATH(Tcpip6), + "", + OldGuid, + NewGuid); - ValuePrefix = __SettingsAllocate(ValuePrefixLength); + (VOID) SettingsCopyIpAddresses(4, + OldLuid, + NewLuid); - status = STATUS_NO_MEMORY; - if (ValuePrefix == NULL) + (VOID) SettingsCopyIpAddresses(6, + OldLuid, + NewLuid); + + SettingsKey = DriverGetSettingsKey(); + + status = RegistryCreateSubKey(SettingsKey, + SubKeyName, + REG_OPTION_NON_VOLATILE, + &SubKey); + if (!NT_SUCCESS(status)) 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); + status = SettingsStoreCurrent(SubKey, + NewGuid, + NewLuid); 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); - - __SettingsFree(ValuePrefix); - - RegistryCloseKey(Key); + RegistryCloseKey(SubKey); -done: Trace("<====\n"); return STATUS_SUCCESS; @@ -476,62 +519,14 @@ done: 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,25 +538,60 @@ SettingsSave( { 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); + status = RegistryOpenSubKey(SettingsKey, + SubKeyName, + KEY_ALL_ACCESS, + &SubKey); if (!NT_SUCCESS(status)) - goto fail1; + 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; - SettingsCopy(SubKey, InterfaceGuid, InterfaceLuid, TRUE); + RtlFreeAnsiString(&Ansi); +done: RegistryCloseKey(SubKey); return STATUS_SUCCESS; +fail3: + Error("fail3\n"); + + RegistryCloseKey(SubKey); + +fail2: + Error("fail2\n"); + + RtlFreeAnsiString(&Ansi); + fail1: Error("fail1\n", status); @@ -579,6 +609,10 @@ SettingsRestore( { HANDLE SettingsKey; HANDLE SubKey; + ANSI_STRING Ansi; + PANSI_STRING NetCfgInstanceId; + PNET_LUID NetLuid; + ULONG NetLuidLength; NTSTATUS status; SettingsKey = DriverGetSettingsKey(); @@ -594,15 +628,65 @@ 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; - SettingsCopy(SubKey, InterfaceGuid, InterfaceLuid, FALSE); + 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); + } + + RtlFreeAnsiString(&Ansi); + + if (NetLuidLength != 0) + RegistryFreeBinaryValue(NetLuid); + + 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 |