|
|
#include "precomp.h"
EXTERN_C VOID WINAPI NetCfgDiagRepairRegistryBindings ( IN FILE* pLogFile);
#define REG_DELETE 100
CONST CHAR Empty[] = "";
typedef union _TR_VALUE_DATA { ULONG_PTR __asignany; ULONG Value; CONST BYTE* Pointer; } TR_VALUE_DATA;
typedef VOID (TR_CONDITIONAL_ROUTINE)( IN CONST struct _TR_REPAIR_CONTEXT *Ctx, IN CONST struct _TR_KEY_DESCRIPTOR *Kd, IN CONST struct _TR_VALUE_DESCRIPTOR *Vd, OUT DWORD *RegType, OUT TR_VALUE_DATA *Data, OUT DWORD *DataSize );
typedef TR_CONDITIONAL_ROUTINE *PTR_CONDITIONAL_ROUTINE;
typedef struct _TR_VALUE_DESCRIPTOR { PCSTR SubKeyName; PCSTR ValueName; DWORD RegType; TR_VALUE_DATA Data; DWORD DataSize;
//
// If Conditional is TRUE, then Data and DataSize are obtained at run-time
// by invoking the routine whose address is in ConditionalRoutine.
// ConditionalData may be used to hold arbitrary information for use by
// ConditionalRoutine.
//
BOOLEAN Conditional; PTR_CONDITIONAL_ROUTINE ConditionalRoutine; TR_VALUE_DATA ConditionalData; } TR_VALUE_DESCRIPTOR;
#define TRV_DW(_subkey, _valuename, _data) \
{ _subkey, _valuename, REG_DWORD, (ULONG_PTR)_data, sizeof(DWORD) },
#define TRV_ESZ(_subkey, _valuename, _esz) \
{ _subkey, _valuename, REG_EXPAND_SZ, (ULONG_PTR)_esz, sizeof(_esz) },
#define TRV_MSZ(_subkey, _valuename, _msz) \
{ _subkey, _valuename, REG_MULTI_SZ, (ULONG_PTR)_msz, sizeof(_msz) },
#define TRV_SZ(_subkey, _valuename, _sz) \
{ _subkey, _valuename, REG_SZ, (ULONG_PTR)_sz, sizeof(_sz) },
#define TRV_DEL(_subkey, _valuename) \
{ _subkey, _valuename, REG_DELETE, 0, 0 },
#define TRV_COND(_subkey, _valuename, _routine, _cdata) \
{ _subkey, _valuename, REG_NONE, 0, 0, TRUE, _routine, _cdata },
#define TRV_END() \
{ NULL, NULL, REG_NONE, 0, 0 }
typedef struct _TR_KEY_DESCRIPTOR { //
// RootKey is one of the HKEY_* values. (e.g. HKEY_LOCAL_MACHINE)
//
HKEY RootKey;
//
// ParentKey is the name of a subkey (under RootKey) where either the
// values reside or subkeys are to be enumerated and values found under
// each subkey.
//
PCSTR ParentKeyName;
//
// TRUE if all subkeys of Parentkey are to be enumerated and values
// found under each of those subkeys.
//
BOOL EnumKey;
//
// Pointer to an array of value descriptors. The array is terminated
// with an entry of all zeros.
//
CONST TR_VALUE_DESCRIPTOR *Value; } TR_KEY_DESCRIPTOR;
#define DHCP_OPT_TCPIP(_name) \
"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\"_name"\0"
#define DHCP_OPT_TCPIP_INTERFACE(_name) \
"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\?\\"_name"\0"
#define DHCP_OPT_LEGACY_TCPIP_INTERFACE(_name) \
"SYSTEM\\CurrentControlSet\\Services\\?\\Parameters\\Tcpip\\"_name"\0"
#define DHCP_OPT_NETBT(_name) \
"SYSTEM\\CurrentControlSet\\Services\\NetBT\\Parameters\\"_name
#define DHCP_OPT_NETBT_INTERFACE(_name) \
"SYSTEM\\CurrentControlSet\\Services\\NetBT\\Parameters\\Interfaces\\Tcpip_?\\"_name"\0"
#define DHCP_OPT_NETBT_ADAPTER(_name) \
"SYSTEM\\CurrentControlSet\\Services\\NetBT\\Adapters\\?\\"_name"\0"
CONST TR_VALUE_DESCRIPTOR DhcpParameterOptions_Values [] = { TRV_DW ("1", "KeyType", 7) TRV_MSZ("1", "RegLocation", DHCP_OPT_TCPIP_INTERFACE ("DhcpSubnetMaskOpt") DHCP_OPT_LEGACY_TCPIP_INTERFACE("DhcpSubnetMaskOpt")) TRV_DW ("3", "KeyType", 7) TRV_MSZ("3", "RegLocation", DHCP_OPT_TCPIP_INTERFACE ("DhcpDefaultGateway") DHCP_OPT_LEGACY_TCPIP_INTERFACE("DhcpDefaultGateway")) TRV_DW ("6", "KeyType", 1) TRV_MSZ("6", "RegLocation", DHCP_OPT_TCPIP_INTERFACE("DhcpNameServer") DHCP_OPT_TCPIP ("DhcpNameServer")) TRV_DW ("15", "KeyType", 1) TRV_MSZ("15", "RegLocation", DHCP_OPT_TCPIP_INTERFACE("DhcpDomain") DHCP_OPT_TCPIP ("DhcpDomain")) TRV_DW ("44", "KeyType", 1) TRV_MSZ("44", "RegLocation", DHCP_OPT_NETBT_INTERFACE("DhcpNameServerList") DHCP_OPT_NETBT_ADAPTER ("DhcpNameServer")) TRV_DW ("46", "KeyType", 4) TRV_SZ ("46", "RegLocation", DHCP_OPT_NETBT("DhcpNodeType")) TRV_DW ("47", "KeyType", 1) TRV_SZ ("47", "RegLocation", DHCP_OPT_NETBT("DhcpScopeID")) TRV_DW ("DhcpNetbiosOptions", "KeyType", 4) TRV_DW ("DhcpNetbiosOptions", "OptionId", 1) TRV_DW ("DhcpNetbiosOptions", "VendorType", 1) TRV_MSZ("DhcpNetbiosOptions", "RegLocation", DHCP_OPT_NETBT_INTERFACE("DhcpNetbiosOptions")) TRV_END() }; CONST TR_KEY_DESCRIPTOR DhcpParameterOptions = { HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Dhcp\\Parameters\\Options", FALSE, DhcpParameterOptions_Values };
CONST TR_VALUE_DESCRIPTOR DhcpParameter_Values [] = { TRV_ESZ(NULL, "ServiceDll", "%SystemRoot%\\System32\\dhcpcsvc.dll") TRV_END() }; CONST TR_KEY_DESCRIPTOR DhcpParameters = { HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Dhcp\\Parameters", FALSE, DhcpParameter_Values };
CONST TR_VALUE_DESCRIPTOR DnscacheParameter_Values [] = { TRV_ESZ(NULL, "ServiceDll", "%SystemRoot%\\System32\\dnsrslvr.dll") TRV_DEL(NULL, "AdapterTimeoutCacheTime") TRV_DEL(NULL, "CacheHashTableBucketSize") TRV_DEL(NULL, "CacheHashTableSize") TRV_DEL(NULL, "DefaultRegistrationRefreshInterval") TRV_DEL(NULL, "MaxCacheEntryTtlLimit") TRV_DEL(NULL, "MaxSoaCacheEntryTtlLimit") TRV_DEL(NULL, "NegativeCacheTime") TRV_DEL(NULL, "NegativeSoaCacheTime") TRV_DEL(NULL, "NetFailureCacheTime") TRV_DEL(NULL, "NetFailureErrorPopupLimit") TRV_END() }; CONST TR_KEY_DESCRIPTOR DnscacheParameters = { HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Dnscache\\Parameters", FALSE, DnscacheParameter_Values };
CONST TR_VALUE_DESCRIPTOR LmHostsParameter_Values [] = { TRV_ESZ(NULL, "ServiceDll", "%SystemRoot%\\System32\\lmhsvc.dll") TRV_END() }; CONST TR_KEY_DESCRIPTOR LmHostsParameters = { HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\LmHosts\\Parameters", FALSE, LmHostsParameter_Values };
CONST TR_VALUE_DESCRIPTOR NetbtInterface_Values [] = { TRV_DEL(NULL, "EnableAdapterDomainNameRegistration") TRV_MSZ(NULL, "NameServerList", "") TRV_DW (NULL, "NetbiosOptions", 0) TRV_END() }; CONST TR_KEY_DESCRIPTOR NetbtInterfaces = { HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Netbt\\Parameters\\Interfaces", TRUE, NetbtInterface_Values };
CONST TR_VALUE_DESCRIPTOR NetbtParameter_Values [] = { TRV_DEL(NULL, "BacklogIncrement") TRV_DW (NULL, "BcastNameQueryCount", 3) TRV_DW (NULL, "BcastQueryTimeout", 750) TRV_DEL(NULL, "BroadcastAddress") TRV_DEL(NULL, "CachePerAdapterEnabled") TRV_DW (NULL, "CacheTimeout", 600000) TRV_DEL(NULL, "ConnectOnRequestedInterfaceOnly") TRV_DEL(NULL, "EnableDns") TRV_DEL(NULL, "EnableLmhosts") TRV_DEL(NULL, "EnableProxy") TRV_DEL(NULL, "EnableProxyRegCheck") TRV_DEL(NULL, "InitialRefreshT.O.") TRV_DEL(NULL, "LmhostsTimeout") TRV_DEL(NULL, "MaxConnBackLog") TRV_DEL(NULL, "MaxDgramBuffering") TRV_DEL(NULL, "MaxPreloadEntries") TRV_DEL(NULL, "MinimumFreeLowerConnections") TRV_DEL(NULL, "MinimumRefreshSleepTime") TRV_DW (NULL, "NameServerPort", 137) TRV_DW (NULL, "NameSrvQueryCount", 3) TRV_DW (NULL, "NameSrvQueryTimeout", 1500) TRV_SZ (NULL, "NbProvider", "_tcp") TRV_DEL(NULL, "NodeType") TRV_DEL(NULL, "NoNameReleaseOnDemand") TRV_DEL(NULL, "RandomAdapter") TRV_DEL(NULL, "RefreshOpCode") TRV_DEL(NULL, "ScopeId") TRV_DW (NULL, "SessionKeepAlive", 3600000) TRV_DEL(NULL, "SingleResponse") TRV_DW (NULL, "Size/Small/Medium/Large", 1) TRV_DEL(NULL, "SmbDeviceEnabled") TRV_SZ (NULL, "TransportBindName", "\\Device\\") TRV_DEL(NULL, "TryAllIpAddrs") TRV_DEL(NULL, "TryAllNameServers") TRV_DEL(NULL, "UseDnsOnlyForNameResolutions") TRV_DEL(NULL, "WinsDownTimeout") TRV_END() }; CONST TR_KEY_DESCRIPTOR NetbtParameters = { HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Netbt\\Parameters", FALSE, NetbtParameter_Values };
CONST TR_VALUE_DESCRIPTOR NlaParameter_Values [] = { TRV_ESZ(NULL, "ServiceDll", "%SystemRoot%\\System32\\mswsock.dll") TRV_END() }; CONST TR_KEY_DESCRIPTOR NlaParameters = { HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Nla\\Parameters", FALSE, NlaParameter_Values };
typedef enum { TrAddressTypeTcpipValue, TrDefaultGatewayMetricTcpipValue, TrDisableDynamicUpdateTcpipValue, TrDontAddDefaultGatewayTcpipValue, TrEnableDhcpTcpipValue, TrNameServerTcpipValue, TrRawIpAllowedProtocolsTcpipValue, TrTcpAllowedPortsTcpipValue, TrUdpAllowedPortsTcpipValue, TrEnableDeadGwDetectTcpipValue, } TR_TCPIP_VALUE;
TR_CONDITIONAL_ROUTINE TrTcpipWanConditionalRoutine; TR_CONDITIONAL_ROUTINE TrTcpipRrasConditionalRoutine;
CONST TR_VALUE_DESCRIPTOR TcpipInterface_Values [] = { TRV_COND(NULL, "AddressType", TrTcpipWanConditionalRoutine, TrAddressTypeTcpipValue) TRV_MSZ (NULL, "DefaultGateway", "") TRV_COND(NULL, "DefaultGatewayMetric", TrTcpipWanConditionalRoutine, TrDefaultGatewayMetricTcpipValue) TRV_COND(NULL, "DisableDynamicUpdate", TrTcpipWanConditionalRoutine, TrDisableDynamicUpdateTcpipValue) TRV_DEL (NULL, "DisableReverseAddressRegistrations") TRV_COND(NULL, "DontAddDefaultGateway", TrTcpipRrasConditionalRoutine, TrDontAddDefaultGatewayTcpipValue) TRV_COND(NULL, "EnableDhcp", TrTcpipWanConditionalRoutine, TrEnableDhcpTcpipValue) TRV_MSZ (NULL, "IpAddress", "0.0.0.0\0") TRV_DEL (NULL, "IpAutoconfigurationAddress") TRV_DEL (NULL, "IpAutoconfigurationEnabled") TRV_DEL (NULL, "IpAutoconfigurationMask") TRV_DEL (NULL, "IpAutoconfigurationSeed") TRV_DEL (NULL, "IpAutoconfigurationSubnet") TRV_DEL (NULL, "MaxForwardPending") TRV_DEL (NULL, "Mtu") TRV_COND(NULL, "NameServer", TrTcpipWanConditionalRoutine, TrNameServerTcpipValue) TRV_DEL (NULL, "PerformRouterDiscovery") TRV_DEL (NULL, "PerformRouterDiscoveryBackup") TRV_DEL (NULL, "PptpFiltering") TRV_COND(NULL, "RawIpAllowedProtocols", TrTcpipWanConditionalRoutine, TrRawIpAllowedProtocolsTcpipValue) TRV_DEL (NULL, "SolicitationAddressBcast") TRV_MSZ (NULL, "SubnetMask", "0.0.0.0\0") TRV_COND(NULL, "TcpAllowedPorts", TrTcpipWanConditionalRoutine, TrTcpAllowedPortsTcpipValue) TRV_DEL (NULL, "TcpDelAckTicks") TRV_DEL (NULL, "TcpInitialRtt") TRV_DEL (NULL, "TcpWindowSize") TRV_DEL (NULL, "TypeOfInterface") TRV_COND(NULL, "UdpAllowedPorts", TrTcpipWanConditionalRoutine, TrUdpAllowedPortsTcpipValue) TRV_DW (NULL, "UseZeroBroadcast", 0) TRV_END () };
CONST TR_KEY_DESCRIPTOR TcpipInterfaces = { HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces", TRUE, TcpipInterface_Values };
CONST TR_VALUE_DESCRIPTOR TcpipParameter_Values [] = { TRV_DEL (NULL, "AllowUnqualifiedQuery") TRV_DEL (NULL, "AllowUserRawAccess") TRV_DEL (NULL, "ArpAlwaysSourceRoute") TRV_DEL (NULL, "ArpCacheLife") TRV_DEL (NULL, "ArpCacheMinReferencedLife") TRV_DEL (NULL, "ArpRetryCount") TRV_DEL (NULL, "ArpTrSingleRoute") TRV_DEL (NULL, "ArpUseEtherSnap") TRV_ESZ (NULL, "DatabasePath", "%SystemRoot%\\System32\\drivers\\etc") TRV_DEL (NULL, "DefaultRegistrationTtl") TRV_DEL (NULL, "DefaultTosValue") TRV_DEL (NULL, "DefaultTtl") TRV_DEL (NULL, "DisableDhcpMediaSense") TRV_DEL (NULL, "DisableDynamicUpdate") TRV_DEL (NULL, "DisableIpSourceRouting") TRV_DEL (NULL, "DisableMediaSenseEventLog") TRV_DEL (NULL, "DisableReplaceAddressesInConflicts") TRV_DEL (NULL, "DisableTaskOffload") TRV_DEL (NULL, "DisableUserTosSetting") TRV_DEL (NULL, "DisjointNameSpace") TRV_DEL (NULL, "DontAddDefaultGatewayDefault") TRV_DEL (NULL, "DnsQueryTimeouts") TRV_DEL (NULL, "EnableAddrMaskReply") TRV_DEL (NULL, "EnableBcastArpReply") TRV_COND(NULL, "EnableDeadGwDetect", TrTcpipRrasConditionalRoutine, TrEnableDeadGwDetectTcpipValue) TRV_DEL (NULL, "EnableFastRouteLookup") TRV_DEL (NULL, "EnableIcmpRedirect") TRV_DEL (NULL, "EnableMulticastForwarding") TRV_DEL (NULL, "EnablePmtuBhDetect") TRV_DEL (NULL, "EnablePmtuDiscovery") TRV_DEL (NULL, "EnableSecurityFilters") TRV_DEL (NULL, "FfpControlFlags") TRV_DEL (NULL, "FfpFastForwardingCacheSize") TRV_DW (NULL, "ForwardBroadcasts", 0) TRV_DEL (NULL, "ForwardBufferMemory") TRV_DEL (NULL, "GlobalMaxTcpWindowSize") TRV_DEL (NULL, "IgmpLevel") TRV_DEL (NULL, "IpAutoconfigurationEnabled") TRV_DEL (NULL, "IpAutoconfigurationMask") TRV_DEL (NULL, "IpAutoconfigurationSeed") TRV_DW (NULL, "IpEnableRouter", 0) TRV_DEL (NULL, "IpEnableRouterBackup") TRV_DEL (NULL, "KeepAliveInterval") TRV_DEL (NULL, "KeepAliveTime") TRV_SZ (NULL, "NameServer", "") TRV_DEL (NULL, "MaxForwardBufferMemory") TRV_DEL (NULL, "MaxFreeTWTcbs") TRV_DEL (NULL, "MaxFreeTcbs") TRV_DEL (NULL, "MaxHashTableSize") TRV_DEL (NULL, "MaxNormLookupMemory") TRV_DEL (NULL, "MaxNumForwardPackets") TRV_DEL (NULL, "MaxUserPort") TRV_DEL (NULL, "NumForwardPackets") TRV_DEL (NULL, "NumTcbTablePartitions") TRV_DEL (NULL, "PptpTcpMaxDataRetransmissions") TRV_DEL (NULL, "PrioritizeRecordData") TRV_DEL (NULL, "QueryIpMatching") TRV_DEL (NULL, "SackOpts") TRV_DEL (NULL, "SearchList") TRV_DEL (NULL, "SynAttackProtect") TRV_DEL (NULL, "Tcp1323Opts") TRV_DEL (NULL, "TcpMaxConnectResponseRetransmissions") TRV_DEL (NULL, "TcpMaxConnectRetransmissions") TRV_DEL (NULL, "TcpMaxDataRetransmissions") TRV_DEL (NULL, "TcpMaxDupAcks") TRV_DEL (NULL, "TcpMaxHalfOpen") TRV_DEL (NULL, "TcpMaxHalfOpenRetried") TRV_DEL (NULL, "TcpMaxPortsExhausted") TRV_DEL (NULL, "TcpMaxSendFree") TRV_DEL (NULL, "TcpNumConnections") TRV_DEL (NULL, "TcpTimedWaitDelay") TRV_DEL (NULL, "TcpUseRfc1122UrgentPointer") TRV_DEL (NULL, "TcpWindowSize") TRV_DEL (NULL, "TrFunctionalMcastAddress") TRV_DEL (NULL, "UpdateSecurityLevel") TRV_DEL (NULL, "UseDomainNameDevolution") TRV_DW ("Winsock", "UseDelayedAcceptance", 0) TRV_END () }; CONST TR_KEY_DESCRIPTOR TcpipParameters = { HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", FALSE, TcpipParameter_Values };
CONST TR_VALUE_DESCRIPTOR TcpipPerformance_Values [] = { TRV_SZ (NULL, "Close", "CloseTcpIpPerformanceData") TRV_SZ (NULL, "Collect", "CollectTcpIpPerformanceData") TRV_SZ (NULL, "Library", "Perfctrs.dll") TRV_SZ (NULL, "Open", "OpenTcpIpPerformanceData") TRV_SZ (NULL, "Object List", "502 510 546 582 638 658") TRV_END() }; CONST TR_KEY_DESCRIPTOR TcpipPerformance = { HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Performance", FALSE, TcpipPerformance_Values };
CONST TR_VALUE_DESCRIPTOR TcpipServiceProvider_Values [] = { TRV_DW (NULL, "Class", 8) TRV_DW (NULL, "DnsPriority", 2000) TRV_DW (NULL, "HostsPriority", 500) TRV_DW (NULL, "LocalPriority", 499) TRV_DW (NULL, "NetbtPriority", 2001) TRV_SZ (NULL, "Name", "TCP/IP") TRV_ESZ(NULL, "ProviderPath", "%SystemRoot%\\System32\\wsock32.dll") TRV_END() }; CONST TR_KEY_DESCRIPTOR TcpipServiceProvider = { HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\ServiceProvider", FALSE, TcpipServiceProvider_Values };
CONST TR_KEY_DESCRIPTOR* TrRepairSet [] = { &DhcpParameterOptions, &DhcpParameters, &DnscacheParameters, &LmHostsParameters, &NetbtInterfaces, &NetbtParameters, &NlaParameters, &TcpipInterfaces, &TcpipParameters, &TcpipPerformance, &TcpipServiceProvider, NULL };
#define SAM_DESIRED KEY_READ | KEY_WRITE | DELETE
typedef enum _TR_LOG_ACTION { TR_ADDED, TR_DELETED, TR_RESET, } TR_LOG_ACTION;
CONST PCSTR LogActionPrefix [] = { "added ", "deleted", "reset ", };
typedef struct _TR_REPAIR_CONTEXT { HANDLE Heap; FILE *LogFile; PBYTE RegData; ULONG RegDataSize; CHAR EnumKeyName [MAX_PATH]; } TR_REPAIR_CONTEXT, *PTR_REPAIR_CTX;
BOOL TrInitializeRepairContext( IN PTR_REPAIR_CTX Ctx, IN FILE *LogFile ) { ZeroMemory(Ctx, sizeof(TR_REPAIR_CONTEXT)); Ctx->Heap = GetProcessHeap(); Ctx->LogFile = LogFile;
Ctx->RegDataSize = 1024; Ctx->RegData = HeapAlloc(Ctx->Heap, 0, Ctx->RegDataSize);
*Ctx->EnumKeyName = 0;
return (Ctx->RegData != NULL); }
VOID TrCleanupRepairContext( IN PTR_REPAIR_CTX Ctx ) { if (Ctx->RegData != NULL) { HeapFree(Ctx->Heap, 0, Ctx->RegData); Ctx->RegData = NULL; } }
VOID TrLogAction( IN TR_LOG_ACTION Action, IN PTR_REPAIR_CTX Ctx, IN CONST TR_KEY_DESCRIPTOR *Kd, IN CONST TR_VALUE_DESCRIPTOR *Vd, IN DWORD RegType ) { fprintf(Ctx->LogFile, "%s %s\\", LogActionPrefix[Action], Kd->ParentKeyName);
if (Vd->SubKeyName != NULL) { fprintf(Ctx->LogFile, "%s\\", Vd->SubKeyName); }
if (Kd->EnumKey) { fprintf(Ctx->LogFile, "%s\\", Ctx->EnumKeyName); }
fprintf(Ctx->LogFile, "%s\n", Vd->ValueName);
//
// Show the value we are replacing.
//
if (TR_RESET == Action) { switch (RegType) { case REG_DWORD: fprintf(Ctx->LogFile, " old REG_DWORD = %d\n\n", *(PULONG)Ctx->RegData); break;
case REG_EXPAND_SZ: fprintf(Ctx->LogFile, " old REG_EXPAND_SZ = %s\n\n", (PCSTR)Ctx->RegData); break;
case REG_MULTI_SZ: { PCSTR Msz = (PCSTR)Ctx->RegData;
fprintf(Ctx->LogFile, " old REG_MULTI_SZ =\n"); if (*Msz) { while (*Msz) { fprintf(Ctx->LogFile, " %s\n", Msz); Msz += strlen(Msz) + 1; } } else { fprintf(Ctx->LogFile, " <empty>\n"); } fprintf(Ctx->LogFile, "\n"); break; }
case REG_SZ: fprintf(Ctx->LogFile, " old REG_SZ = %s\n\n", (PCSTR)Ctx->RegData); break;
default: break; } } }
LONG TrReadRegData( IN PTR_REPAIR_CTX Ctx, IN HKEY Key, IN CONST TR_VALUE_DESCRIPTOR *Vd, OUT PULONG ReturnedSize ) { LONG Error; ULONG Type, Size;
*ReturnedSize = 0;
Size = Ctx->RegDataSize; Error = RegQueryValueExA(Key, Vd->ValueName, NULL, &Type, Ctx->RegData, &Size);
if (ERROR_MORE_DATA == Error) { HeapFree(Ctx->Heap, 0, Ctx->RegData); Ctx->RegDataSize = (Size + 63) & ~63; Ctx->RegData = HeapAlloc(Ctx->Heap, 0, Ctx->RegDataSize);
if (Ctx->RegData != NULL) { Size = Ctx->RegDataSize; Error = RegQueryValueExA(Key, Vd->ValueName, NULL, &Type, Ctx->RegData, &Size); if (NOERROR != Error) { fprintf(Ctx->LogFile, " RegQueryValueEx still failed. error = %d\n", Error); } else { *ReturnedSize = Size; } } else { Error = ERROR_NOT_ENOUGH_MEMORY; } } else if (NOERROR == Error) { *ReturnedSize = Size; }
return Error; }
VOID TrSetRegData( IN HKEY Key, IN CONST TR_VALUE_DESCRIPTOR *Vd, IN DWORD RegType, IN TR_VALUE_DATA* Data, IN DWORD DataSize ) { RegSetValueExA(Key, Vd->ValueName, 0, RegType, (REG_DWORD == RegType) ? (CONST BYTE*)&Data->Value : Data->Pointer, DataSize); }
VOID TrProcessOpenKey( IN PTR_REPAIR_CTX Ctx, IN HKEY ParentKey, IN CONST TR_KEY_DESCRIPTOR *Kd ) { LONG Error = NOERROR; ULONG i, Size; CONST TR_VALUE_DESCRIPTOR *Vd, *PrevVd; HKEY SubKey, UseKey; DWORD RegType; TR_VALUE_DATA Data; DWORD DataSize;
PrevVd = NULL; SubKey = INVALID_HANDLE_VALUE;
for (i = 0; Kd->Value[i].ValueName != NULL; i++) { Vd = &Kd->Value[i];
if (Vd->SubKeyName == NULL) { UseKey = ParentKey; Error = NOERROR; }
//
// Open a subkey if needed, and only if its not the same as
// the one already open.
//
else if (((PrevVd == NULL) || (Vd->SubKeyName != PrevVd->SubKeyName))) {
if (SubKey != INVALID_HANDLE_VALUE) { RegCloseKey(SubKey); }
Error = RegOpenKeyExA(ParentKey, Vd->SubKeyName, 0, SAM_DESIRED, &SubKey); if (NOERROR == Error) { UseKey = SubKey; } else { SubKey = INVALID_HANDLE_VALUE; } }
if (NOERROR == Error) { Error = TrReadRegData(Ctx, UseKey, Vd, &Size); }
//
// If the key is handled specially, consult its conditional-routine
// to obtain the settings to be used below. From here onwards,
// all processing for this value must use the local variables
// 'RegType', 'Data', and 'DataSize' rather than the corresponding
// fields of 'Vd'.
//
// (Also see 'TrSetRegData' and 'TrLogAction'.)
//
if (Vd->Conditional) { Vd->ConditionalRoutine(Ctx, Kd, Vd, &RegType, &Data, &DataSize); } else { RegType = Vd->RegType; Data = Vd->Data; DataSize = Vd->DataSize; }
if (ERROR_FILE_NOT_FOUND == Error) {
if (REG_DELETE != RegType) { //
// The value should exist, so set its default value.
//
TrSetRegData(UseKey, Vd, RegType, &Data, DataSize); TrLogAction(TR_ADDED, Ctx, Kd, Vd, RegType); }
} else if (NOERROR == Error) { //
// The value exists and we read its data.
//
if (REG_DELETE == RegType) { //
// Need to delete the existing value.
//
RegDeleteValueA(UseKey, Vd->ValueName); TrLogAction(TR_DELETED, Ctx, Kd, Vd, RegType); } else { BOOL MisCompare = TRUE; //
// Compare the value we read with the default value and reset
// it if it is different.
//
if (Size == DataSize) { if (REG_DWORD == RegType) { MisCompare = (*(PULONG)Ctx->RegData != Data.Value); } else { MisCompare = memcmp(Ctx->RegData, Data.Pointer, Size); } } if (MisCompare) { TrSetRegData(UseKey, Vd, RegType, &Data, DataSize); TrLogAction(TR_RESET, Ctx, Kd, Vd, RegType); } }
} else { fprintf(Ctx->LogFile, "\nerror reading registry value (%s) (%d)\n", Vd->ValueName, Error); }
PrevVd = Vd; }
if (SubKey != INVALID_HANDLE_VALUE) { RegCloseKey(SubKey); } }
VOID TrProcessKey( IN PTR_REPAIR_CTX Ctx, IN CONST TR_KEY_DESCRIPTOR *Kd ) { LONG Error; HKEY ParentKey;
Error = RegOpenKeyExA(Kd->RootKey, Kd->ParentKeyName, 0, SAM_DESIRED, &ParentKey); if (NOERROR == Error) {
if (Kd->EnumKey) { ULONG i; ULONG EnumKeyNameLen; FILETIME LastWriteTime; HKEY SubKey;
for (i = 0; NOERROR == Error; i++) { EnumKeyNameLen = sizeof(Ctx->EnumKeyName); Error = RegEnumKeyExA(ParentKey, i, Ctx->EnumKeyName, &EnumKeyNameLen, NULL, NULL, NULL, &LastWriteTime); if (NOERROR != Error) { if (ERROR_NO_MORE_ITEMS != Error) { fprintf(Ctx->LogFile, "enum error = %d (index = %d)\n", Error, i); } break; }
Error = RegOpenKeyExA(ParentKey, Ctx->EnumKeyName, 0, SAM_DESIRED, &SubKey); if (NOERROR == Error) { TrProcessOpenKey(Ctx, SubKey, Kd);
RegCloseKey(SubKey); } } } else { TrProcessOpenKey(Ctx, ParentKey, Kd); }
RegCloseKey(ParentKey); } }
VOID TrProcessSet( IN PTR_REPAIR_CTX Ctx, IN CONST TR_KEY_DESCRIPTOR *Set[] ) { ULONG i;
//
// Process each TR_KEY_DESCRIPTOR element in the set.
//
for (i = 0; Set[i] != NULL; i++) { TrProcessKey(Ctx, Set[i]); } }
DWORD TrRepair( FILE* LogFile ) { TR_REPAIR_CONTEXT Ctx;
if (TrInitializeRepairContext(&Ctx, LogFile)) {
TrProcessSet(&Ctx, TrRepairSet);
NetCfgDiagRepairRegistryBindings(LogFile);
TrCleanupRepairContext(&Ctx); }
return NOERROR; }
BOOLEAN IsRrasInstalled( IN CONST struct _TR_REPAIR_CONTEXT *Ctx, IN CONST struct _TR_KEY_DESCRIPTOR *Kd ) { ULONG Error; BOOLEAN RrasInstalled; HKEY RrasKey; CONST CHAR RrasKeyName[] = "SYSTEM\\CurrentControlSet\\Services\\RemoteAccess";
Error = RegOpenKeyExA(Kd->RootKey, RrasKeyName, 0, SAM_DESIRED, &RrasKey);
if (NOERROR != Error) { RrasInstalled = FALSE; } else { DWORD ConfigurationFlags; DWORD Size; DWORD Type; Size = sizeof(DWORD); Error = RegQueryValueExA(RrasKey, "ConfigurationFlags", NULL, &Type, (LPBYTE)&ConfigurationFlags, &Size); if (NOERROR != Error) { RrasInstalled = FALSE; } else { RrasInstalled = (ConfigurationFlags != 0); } RegCloseKey(RrasKey); }
return RrasInstalled; }
BOOLEAN IsWanInterface( IN CONST struct _TR_REPAIR_CONTEXT *Ctx, IN CONST struct _TR_KEY_DESCRIPTOR *Kd ) { HKEY AdaptersKey; CONST CHAR AdaptersKeyName[] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters"; LONG Error; BOOLEAN IsWan; HKEY Key;
//
// Open the TCP/IP adapters key.
// If successful, look for a subkey with the same name
// as the one in 'Kd'. If present, this is not a LAN interface.
//
Error = RegOpenKeyExA(Kd->RootKey, AdaptersKeyName, 0, SAM_DESIRED, &AdaptersKey); if (NOERROR != Error) { //
// Assume this is a LAN interface.
//
IsWan = FALSE; } else { Error = RegOpenKeyExA(AdaptersKey, Ctx->EnumKeyName, 0, SAM_DESIRED, &Key); if (NOERROR != Error) { IsWan = TRUE; } else { IsWan = FALSE; RegCloseKey(Key); } RegCloseKey(AdaptersKey); }
return IsWan; }
VOID TrTcpipWanConditionalRoutine( IN CONST struct _TR_REPAIR_CONTEXT *Ctx, IN CONST struct _TR_KEY_DESCRIPTOR *Kd, IN CONST struct _TR_VALUE_DESCRIPTOR *Vd, OUT DWORD *RegType, OUT TR_VALUE_DATA *Data, OUT DWORD *DataSize ) { //
// Return the appropriate setting for the given registry value,
// based on whether its key is for a WAN or LAN interface.
//
if (IsWanInterface(Ctx, Kd)) { switch((TR_TCPIP_VALUE)Vd->ConditionalData.Value) {
case TrAddressTypeTcpipValue: case TrDefaultGatewayMetricTcpipValue: case TrDisableDynamicUpdateTcpipValue: case TrNameServerTcpipValue: case TrRawIpAllowedProtocolsTcpipValue: case TrTcpAllowedPortsTcpipValue: case TrUdpAllowedPortsTcpipValue: default: *RegType = REG_DELETE; break;
case TrEnableDhcpTcpipValue: case TrDontAddDefaultGatewayTcpipValue: *RegType = REG_DWORD; Data->Value = 0; *DataSize = sizeof(DWORD); break; } } else { switch((TR_TCPIP_VALUE)Vd->ConditionalData.Value) {
case TrDontAddDefaultGatewayTcpipValue: default: *RegType = REG_DELETE; break;
case TrAddressTypeTcpipValue: case TrDisableDynamicUpdateTcpipValue: *RegType = REG_DWORD; Data->Value = 0; *DataSize = sizeof(DWORD); break;
case TrEnableDhcpTcpipValue: *RegType = REG_DWORD; Data->Value = 1; *DataSize = sizeof(DWORD); break;
case TrNameServerTcpipValue: *RegType = REG_SZ; Data->Pointer = Empty; *DataSize = sizeof(Empty); break;
case TrDefaultGatewayMetricTcpipValue: case TrRawIpAllowedProtocolsTcpipValue: case TrTcpAllowedPortsTcpipValue: case TrUdpAllowedPortsTcpipValue: *RegType = REG_MULTI_SZ; Data->Pointer = Empty; *DataSize = sizeof(Empty); break; } } }
VOID TrTcpipRrasConditionalRoutine( IN CONST struct _TR_REPAIR_CONTEXT *Ctx, IN CONST struct _TR_KEY_DESCRIPTOR *Kd, IN CONST struct _TR_VALUE_DESCRIPTOR *Vd, OUT DWORD *RegType, OUT TR_VALUE_DATA *Data, OUT DWORD *DataSize ) { //
// Return the appropriate setting for the given registry value,
// based on whether RRAS is installed.
//
// N.B. The setting for 'DontAddDefaultGateway' is further dependent
// on whether the key is for a WAN or LAN interface.
//
if (IsRrasInstalled(Ctx, Kd)) { switch((TR_TCPIP_VALUE)Vd->ConditionalData.Value) { case TrDontAddDefaultGatewayTcpipValue: if (IsWanInterface(Ctx, Kd)) { *RegType = REG_DWORD; Data->Value = 1; *DataSize = sizeof(DWORD); } else { *RegType = REG_DELETE; } break; case TrEnableDeadGwDetectTcpipValue: *RegType = REG_DWORD; Data->Value = 0; *DataSize = sizeof(DWORD); break; default: *RegType = REG_DELETE; break; } } else { switch((TR_TCPIP_VALUE)Vd->ConditionalData.Value) { case TrDontAddDefaultGatewayTcpipValue: case TrEnableDeadGwDetectTcpipValue: default: *RegType = REG_DELETE; break; } } }
|