895 lines
26 KiB
C
895 lines
26 KiB
C
#include "precomp.h"
|
|
|
|
EXTERN_C
|
|
VOID
|
|
WINAPI
|
|
NetCfgDiagRepairRegistryBindings (
|
|
IN FILE* pLogFile);
|
|
|
|
|
|
#define REG_DELETE 100
|
|
|
|
typedef enum {
|
|
COND_NONE,
|
|
COND_VALUE,
|
|
COND_ADD,
|
|
COND_DELETE,
|
|
} CONDITIONAL;
|
|
|
|
typedef struct _TR_VALUE_DESCRIPTOR {
|
|
PCSTR SubKeyName;
|
|
PCSTR ValueName;
|
|
DWORD RegType;
|
|
union {
|
|
ULONG_PTR __asignany;
|
|
ULONG DataValue;
|
|
CONST BYTE *DataPointer;
|
|
};
|
|
DWORD DataSize;
|
|
|
|
//
|
|
// If Conditional is not COND_NONE, then the value is conditionally
|
|
// dependent on the presence of a key of the same name under the
|
|
// ConditionalParentKeyName. If the key is present, the values
|
|
// below are used. If not the values above are used.
|
|
//
|
|
// If Conditional is COND_ADD, then the value is added/set if
|
|
// if the conditional key is present, and deleted if it is not present.
|
|
//
|
|
// If Conditional is COND_DELETE, then the value is added/set if
|
|
// the conditional key is NOT present, and deleted if it is present.
|
|
//
|
|
CONDITIONAL Conditional;
|
|
union {
|
|
ULONG_PTR __asignany2;
|
|
ULONG ConditionalDataValue;
|
|
CONST BYTE *ConditionalDataPointer;
|
|
};
|
|
} TR_VALUE_DESCRIPTOR;
|
|
|
|
#define TRV_DW(_subkey, _valuename, _data) \
|
|
{ _subkey, _valuename, REG_DWORD, (ULONG_PTR)_data, sizeof(DWORD) },
|
|
|
|
#define TRV_DW_CV(_subkey, _valuename, _datafalse, _datatrue) \
|
|
{ _subkey, _valuename, REG_DWORD, (ULONG_PTR)_datafalse, sizeof(DWORD), \
|
|
COND_VALUE, (ULONG_PTR)_datatrue },
|
|
|
|
#define TRV_DW_CA(_subkey, _valuename, _data) \
|
|
{ _subkey, _valuename, REG_DWORD, 0, sizeof(DWORD), COND_ADD, \
|
|
(ULONG_PTR)_data },
|
|
|
|
#define TRV_DW_CD(_subkey, _valuename, _data) \
|
|
{ _subkey, _valuename, REG_DWORD, (ULONG_PTR)_data, sizeof(DWORD), \
|
|
COND_DELETE, 0 },
|
|
|
|
#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_MSZ_CA(_subkey, _valuename, _msz) \
|
|
{ _subkey, _valuename, REG_MULTI_SZ, 0, sizeof(_msz), COND_ADD, \
|
|
(ULONG_PTR)_msz },
|
|
|
|
#define TRV_SZ(_subkey, _valuename, _sz) \
|
|
{ _subkey, _valuename, REG_SZ, (ULONG_PTR)_sz, sizeof(_sz) },
|
|
|
|
#define TRV_SZ_CA(_subkey, _valuename, _sz) \
|
|
{ _subkey, _valuename, REG_SZ, 0, sizeof(_sz), COND_ADD, \
|
|
(ULONG_PTR)_sz },
|
|
|
|
#define TRV_DEL(_subkey, _valuename) \
|
|
{ _subkey, _valuename, REG_DELETE, 0, 0 },
|
|
|
|
#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;
|
|
|
|
//
|
|
// ConditionalParentKeyName is the name of a subkey (under RootKey)
|
|
// where a value/subkey may reside, whose presence or lack thereof
|
|
// may affect the values set under subkeys of ParentKeyName.
|
|
//
|
|
PCSTR ConditionalParentKeyName;
|
|
} 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
|
|
};
|
|
|
|
|
|
CONST TR_VALUE_DESCRIPTOR TcpipInterface_Values [] =
|
|
{
|
|
TRV_DW_CA (NULL, "AddressType", 0)
|
|
TRV_MSZ (NULL, "DefaultGateway", "")
|
|
TRV_MSZ_CA(NULL, "DefaultGatewayMetric", "")
|
|
TRV_DW_CA (NULL, "DisableDynamicUpdate", 0)
|
|
TRV_DEL (NULL, "DisableReverseAddressRegistrations")
|
|
TRV_DW_CD (NULL, "DontAddDefaultGateway", 0)
|
|
TRV_DW_CV (NULL, "EnableDhcp", 0, 1)
|
|
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_SZ_CA (NULL, "NameServer", "")
|
|
TRV_DEL (NULL, "PerformRouterDiscovery")
|
|
TRV_DEL (NULL, "PerformRouterDiscoveryBackup")
|
|
TRV_DEL (NULL, "PptpFiltering")
|
|
TRV_MSZ_CA(NULL, "RawIpAllowedProtocols", "")
|
|
TRV_DEL (NULL, "SolicitationAddressBcast")
|
|
TRV_MSZ (NULL, "SubnetMask", "0.0.0.0\0")
|
|
TRV_MSZ_CA(NULL, "TcpAllowedPorts", "")
|
|
TRV_DEL (NULL, "TcpDelAckTicks")
|
|
TRV_DEL (NULL, "TcpInitialRtt")
|
|
TRV_DEL (NULL, "TcpWindowSize")
|
|
TRV_DEL (NULL, "TypeOfInterface")
|
|
TRV_MSZ_CA(NULL, "UdpAllowedPorts", "")
|
|
TRV_DW (NULL, "UseZeroBroadcast", 0)
|
|
TRV_END ()
|
|
};
|
|
CONST TR_KEY_DESCRIPTOR TcpipInterfaces =
|
|
{
|
|
HKEY_LOCAL_MACHINE,
|
|
"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces",
|
|
TRUE,
|
|
TcpipInterface_Values,
|
|
"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters",
|
|
};
|
|
|
|
|
|
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_DEL(NULL, "EnableDeadGwDetect")
|
|
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
|
|
)
|
|
{
|
|
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 (Vd->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 BOOLEAN ConditionalKeyPresent
|
|
)
|
|
{
|
|
CONST BYTE *Data;
|
|
|
|
ConditionalKeyPresent &= (Vd->Conditional != COND_NONE);
|
|
|
|
if (REG_DWORD == Vd->RegType) {
|
|
Data = (CONST BYTE*)((ConditionalKeyPresent)? &Vd->ConditionalDataValue : &Vd->DataValue);
|
|
} else {
|
|
Data = (ConditionalKeyPresent)? Vd->ConditionalDataPointer : Vd->DataPointer;
|
|
}
|
|
|
|
RegSetValueExA(Key, Vd->ValueName, 0, Vd->RegType, Data, Vd->DataSize);
|
|
}
|
|
|
|
BOOLEAN
|
|
TrKeyShouldExist(
|
|
IN CONST TR_VALUE_DESCRIPTOR *Vd,
|
|
IN BOOLEAN ConditionalKeyPresent
|
|
)
|
|
{
|
|
if (REG_DELETE == Vd->RegType) {
|
|
return FALSE;
|
|
}
|
|
|
|
if ((Vd->Conditional == COND_ADD) && !ConditionalKeyPresent) {
|
|
return FALSE;
|
|
}
|
|
|
|
if ((Vd->Conditional == COND_DELETE) && ConditionalKeyPresent) {
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
VOID
|
|
TrProcessOpenKey(
|
|
IN PTR_REPAIR_CTX Ctx,
|
|
IN HKEY ParentKey,
|
|
IN BOOLEAN ConditionalKeyPresent,
|
|
IN CONST TR_KEY_DESCRIPTOR *Kd
|
|
)
|
|
{
|
|
LONG Error;
|
|
ULONG i, Size;
|
|
CONST TR_VALUE_DESCRIPTOR *Vd, *PrevVd;
|
|
HKEY SubKey, UseKey;
|
|
|
|
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;
|
|
}
|
|
|
|
//
|
|
// 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;
|
|
}
|
|
}
|
|
|
|
Error = TrReadRegData(Ctx, UseKey, Vd, &Size);
|
|
|
|
if (ERROR_FILE_NOT_FOUND == Error) {
|
|
|
|
if (TrKeyShouldExist(Vd, ConditionalKeyPresent)) {
|
|
//
|
|
// The value should exist, so set its default value.
|
|
//
|
|
TrSetRegData(UseKey, Vd, ConditionalKeyPresent);
|
|
TrLogAction(TR_ADDED, Ctx, Kd, Vd);
|
|
}
|
|
|
|
} else if (NOERROR == Error) {
|
|
//
|
|
// The value exists and we read its data.
|
|
//
|
|
if (!TrKeyShouldExist(Vd, ConditionalKeyPresent)) {
|
|
//
|
|
// Need to delete the existing value.
|
|
//
|
|
RegDeleteValueA(UseKey, Vd->ValueName);
|
|
TrLogAction(TR_DELETED, Ctx, Kd, Vd);
|
|
} else {
|
|
BOOL MisCompare = TRUE;
|
|
//
|
|
// Compare the value we read with the default value and reset
|
|
// it if it is different.
|
|
//
|
|
if (Size == Vd->DataSize) {
|
|
if (REG_DWORD == Vd->RegType) {
|
|
MisCompare = (*(PULONG)Ctx->RegData != ((ConditionalKeyPresent && (Vd->Conditional != COND_NONE))? Vd->ConditionalDataValue : Vd->DataValue));
|
|
} else {
|
|
MisCompare = memcmp(Ctx->RegData, (ConditionalKeyPresent && (Vd->Conditional != COND_NONE))? Vd->ConditionalDataPointer : Vd->DataPointer, Size);
|
|
}
|
|
}
|
|
if (MisCompare) {
|
|
TrSetRegData(UseKey, Vd, ConditionalKeyPresent);
|
|
TrLogAction(TR_RESET, Ctx, Kd, Vd);
|
|
}
|
|
}
|
|
|
|
} 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, ConditionalParentKey;
|
|
BOOLEAN ConditionalKeyPresent;
|
|
|
|
Error = RegOpenKeyExA(Kd->RootKey, Kd->ConditionalParentKeyName, 0,
|
|
SAM_DESIRED, &ConditionalParentKey);
|
|
if (NOERROR != Error) {
|
|
ConditionalParentKey = NULL;
|
|
}
|
|
|
|
Error = RegOpenKeyExA(Kd->RootKey, Kd->ParentKeyName, 0,
|
|
SAM_DESIRED, &ParentKey);
|
|
if (NOERROR == Error) {
|
|
|
|
if (Kd->EnumKey) {
|
|
ULONG i;
|
|
ULONG EnumKeyNameLen;
|
|
FILETIME LastWriteTime;
|
|
HKEY SubKey, ConditionalSubKey;
|
|
|
|
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;
|
|
}
|
|
|
|
ConditionalKeyPresent = FALSE;
|
|
if (ConditionalParentKey) {
|
|
Error = RegOpenKeyExA(ConditionalParentKey,
|
|
Ctx->EnumKeyName, 0,
|
|
SAM_DESIRED, &ConditionalSubKey);
|
|
if (NO_ERROR == Error) {
|
|
RegCloseKey(ConditionalSubKey);
|
|
ConditionalKeyPresent = TRUE;
|
|
}
|
|
}
|
|
|
|
Error = RegOpenKeyExA(ParentKey, Ctx->EnumKeyName, 0,
|
|
SAM_DESIRED, &SubKey);
|
|
if (NOERROR == Error) {
|
|
TrProcessOpenKey(Ctx, SubKey, ConditionalKeyPresent, Kd);
|
|
|
|
RegCloseKey(SubKey);
|
|
}
|
|
}
|
|
} else {
|
|
TrProcessOpenKey(Ctx, ParentKey, FALSE, Kd);
|
|
}
|
|
|
|
RegCloseKey(ParentKey);
|
|
}
|
|
|
|
if (ConditionalParentKey) {
|
|
RegCloseKey(ConditionalParentKey);
|
|
}
|
|
}
|
|
|
|
|
|
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;
|
|
}
|
|
|