Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

894 lines
26 KiB

  1. #include "precomp.h"
  2. EXTERN_C
  3. VOID
  4. WINAPI
  5. NetCfgDiagRepairRegistryBindings (
  6. IN FILE* pLogFile);
  7. #define REG_DELETE 100
  8. typedef enum {
  9. COND_NONE,
  10. COND_VALUE,
  11. COND_ADD,
  12. COND_DELETE,
  13. } CONDITIONAL;
  14. typedef struct _TR_VALUE_DESCRIPTOR {
  15. PCSTR SubKeyName;
  16. PCSTR ValueName;
  17. DWORD RegType;
  18. union {
  19. ULONG_PTR __asignany;
  20. ULONG DataValue;
  21. CONST BYTE *DataPointer;
  22. };
  23. DWORD DataSize;
  24. //
  25. // If Conditional is not COND_NONE, then the value is conditionally
  26. // dependent on the presence of a key of the same name under the
  27. // ConditionalParentKeyName. If the key is present, the values
  28. // below are used. If not the values above are used.
  29. //
  30. // If Conditional is COND_ADD, then the value is added/set if
  31. // if the conditional key is present, and deleted if it is not present.
  32. //
  33. // If Conditional is COND_DELETE, then the value is added/set if
  34. // the conditional key is NOT present, and deleted if it is present.
  35. //
  36. CONDITIONAL Conditional;
  37. union {
  38. ULONG_PTR __asignany2;
  39. ULONG ConditionalDataValue;
  40. CONST BYTE *ConditionalDataPointer;
  41. };
  42. } TR_VALUE_DESCRIPTOR;
  43. #define TRV_DW(_subkey, _valuename, _data) \
  44. { _subkey, _valuename, REG_DWORD, (ULONG_PTR)_data, sizeof(DWORD) },
  45. #define TRV_DW_CV(_subkey, _valuename, _datafalse, _datatrue) \
  46. { _subkey, _valuename, REG_DWORD, (ULONG_PTR)_datafalse, sizeof(DWORD), \
  47. COND_VALUE, (ULONG_PTR)_datatrue },
  48. #define TRV_DW_CA(_subkey, _valuename, _data) \
  49. { _subkey, _valuename, REG_DWORD, 0, sizeof(DWORD), COND_ADD, \
  50. (ULONG_PTR)_data },
  51. #define TRV_DW_CD(_subkey, _valuename, _data) \
  52. { _subkey, _valuename, REG_DWORD, (ULONG_PTR)_data, sizeof(DWORD), \
  53. COND_DELETE, 0 },
  54. #define TRV_ESZ(_subkey, _valuename, _esz) \
  55. { _subkey, _valuename, REG_EXPAND_SZ, (ULONG_PTR)_esz, sizeof(_esz) },
  56. #define TRV_MSZ(_subkey, _valuename, _msz) \
  57. { _subkey, _valuename, REG_MULTI_SZ, (ULONG_PTR)_msz, sizeof(_msz) },
  58. #define TRV_MSZ_CA(_subkey, _valuename, _msz) \
  59. { _subkey, _valuename, REG_MULTI_SZ, 0, sizeof(_msz), COND_ADD, \
  60. (ULONG_PTR)_msz },
  61. #define TRV_SZ(_subkey, _valuename, _sz) \
  62. { _subkey, _valuename, REG_SZ, (ULONG_PTR)_sz, sizeof(_sz) },
  63. #define TRV_SZ_CA(_subkey, _valuename, _sz) \
  64. { _subkey, _valuename, REG_SZ, 0, sizeof(_sz), COND_ADD, \
  65. (ULONG_PTR)_sz },
  66. #define TRV_DEL(_subkey, _valuename) \
  67. { _subkey, _valuename, REG_DELETE, 0, 0 },
  68. #define TRV_END() \
  69. { NULL, NULL, REG_NONE, 0, 0 }
  70. typedef struct _TR_KEY_DESCRIPTOR {
  71. //
  72. // RootKey is one of the HKEY_* values. (e.g. HKEY_LOCAL_MACHINE)
  73. //
  74. HKEY RootKey;
  75. //
  76. // ParentKey is the name of a subkey (under RootKey) where either the
  77. // values reside or subkeys are to be enumerated and values found under
  78. // each subkey.
  79. //
  80. PCSTR ParentKeyName;
  81. //
  82. // TRUE if all subkeys of Parentkey are to be enumerated and values
  83. // found under each of those subkeys.
  84. //
  85. BOOL EnumKey;
  86. //
  87. // Pointer to an array of value descriptors. The array is terminated
  88. // with an entry of all zeros.
  89. //
  90. CONST TR_VALUE_DESCRIPTOR *Value;
  91. //
  92. // ConditionalParentKeyName is the name of a subkey (under RootKey)
  93. // where a value/subkey may reside, whose presence or lack thereof
  94. // may affect the values set under subkeys of ParentKeyName.
  95. //
  96. PCSTR ConditionalParentKeyName;
  97. } TR_KEY_DESCRIPTOR;
  98. #define DHCP_OPT_TCPIP(_name) \
  99. "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\"_name"\0"
  100. #define DHCP_OPT_TCPIP_INTERFACE(_name) \
  101. "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\?\\"_name"\0"
  102. #define DHCP_OPT_LEGACY_TCPIP_INTERFACE(_name) \
  103. "SYSTEM\\CurrentControlSet\\Services\\?\\Parameters\\Tcpip\\"_name"\0"
  104. #define DHCP_OPT_NETBT(_name) \
  105. "SYSTEM\\CurrentControlSet\\Services\\NetBT\\Parameters\\"_name
  106. #define DHCP_OPT_NETBT_INTERFACE(_name) \
  107. "SYSTEM\\CurrentControlSet\\Services\\NetBT\\Parameters\\Interfaces\\Tcpip_?\\"_name"\0"
  108. #define DHCP_OPT_NETBT_ADAPTER(_name) \
  109. "SYSTEM\\CurrentControlSet\\Services\\NetBT\\Adapters\\?\\"_name"\0"
  110. CONST TR_VALUE_DESCRIPTOR DhcpParameterOptions_Values [] =
  111. {
  112. TRV_DW ("1", "KeyType", 7)
  113. TRV_MSZ("1", "RegLocation", DHCP_OPT_TCPIP_INTERFACE ("DhcpSubnetMaskOpt")
  114. DHCP_OPT_LEGACY_TCPIP_INTERFACE("DhcpSubnetMaskOpt"))
  115. TRV_DW ("3", "KeyType", 7)
  116. TRV_MSZ("3", "RegLocation", DHCP_OPT_TCPIP_INTERFACE ("DhcpDefaultGateway")
  117. DHCP_OPT_LEGACY_TCPIP_INTERFACE("DhcpDefaultGateway"))
  118. TRV_DW ("6", "KeyType", 1)
  119. TRV_MSZ("6", "RegLocation", DHCP_OPT_TCPIP_INTERFACE("DhcpNameServer")
  120. DHCP_OPT_TCPIP ("DhcpNameServer"))
  121. TRV_DW ("15", "KeyType", 1)
  122. TRV_MSZ("15", "RegLocation", DHCP_OPT_TCPIP_INTERFACE("DhcpDomain")
  123. DHCP_OPT_TCPIP ("DhcpDomain"))
  124. TRV_DW ("44", "KeyType", 1)
  125. TRV_MSZ("44", "RegLocation", DHCP_OPT_NETBT_INTERFACE("DhcpNameServerList")
  126. DHCP_OPT_NETBT_ADAPTER ("DhcpNameServer"))
  127. TRV_DW ("46", "KeyType", 4)
  128. TRV_SZ ("46", "RegLocation", DHCP_OPT_NETBT("DhcpNodeType"))
  129. TRV_DW ("47", "KeyType", 1)
  130. TRV_SZ ("47", "RegLocation", DHCP_OPT_NETBT("DhcpScopeID"))
  131. TRV_DW ("DhcpNetbiosOptions", "KeyType", 4)
  132. TRV_DW ("DhcpNetbiosOptions", "OptionId", 1)
  133. TRV_DW ("DhcpNetbiosOptions", "VendorType", 1)
  134. TRV_MSZ("DhcpNetbiosOptions", "RegLocation", DHCP_OPT_NETBT_INTERFACE("DhcpNetbiosOptions"))
  135. TRV_END()
  136. };
  137. CONST TR_KEY_DESCRIPTOR DhcpParameterOptions =
  138. {
  139. HKEY_LOCAL_MACHINE,
  140. "SYSTEM\\CurrentControlSet\\Services\\Dhcp\\Parameters\\Options",
  141. FALSE,
  142. DhcpParameterOptions_Values
  143. };
  144. CONST TR_VALUE_DESCRIPTOR DhcpParameter_Values [] =
  145. {
  146. TRV_ESZ(NULL, "ServiceDll", "%SystemRoot%\\System32\\dhcpcsvc.dll")
  147. TRV_END()
  148. };
  149. CONST TR_KEY_DESCRIPTOR DhcpParameters =
  150. {
  151. HKEY_LOCAL_MACHINE,
  152. "SYSTEM\\CurrentControlSet\\Services\\Dhcp\\Parameters",
  153. FALSE,
  154. DhcpParameter_Values
  155. };
  156. CONST TR_VALUE_DESCRIPTOR DnscacheParameter_Values [] =
  157. {
  158. TRV_ESZ(NULL, "ServiceDll", "%SystemRoot%\\System32\\dnsrslvr.dll")
  159. TRV_DEL(NULL, "AdapterTimeoutCacheTime")
  160. TRV_DEL(NULL, "CacheHashTableBucketSize")
  161. TRV_DEL(NULL, "CacheHashTableSize")
  162. TRV_DEL(NULL, "DefaultRegistrationRefreshInterval")
  163. TRV_DEL(NULL, "MaxCacheEntryTtlLimit")
  164. TRV_DEL(NULL, "MaxSoaCacheEntryTtlLimit")
  165. TRV_DEL(NULL, "NegativeCacheTime")
  166. TRV_DEL(NULL, "NegativeSoaCacheTime")
  167. TRV_DEL(NULL, "NetFailureCacheTime")
  168. TRV_DEL(NULL, "NetFailureErrorPopupLimit")
  169. TRV_END()
  170. };
  171. CONST TR_KEY_DESCRIPTOR DnscacheParameters =
  172. {
  173. HKEY_LOCAL_MACHINE,
  174. "SYSTEM\\CurrentControlSet\\Services\\Dnscache\\Parameters",
  175. FALSE,
  176. DnscacheParameter_Values
  177. };
  178. CONST TR_VALUE_DESCRIPTOR LmHostsParameter_Values [] =
  179. {
  180. TRV_ESZ(NULL, "ServiceDll", "%SystemRoot%\\System32\\lmhsvc.dll")
  181. TRV_END()
  182. };
  183. CONST TR_KEY_DESCRIPTOR LmHostsParameters =
  184. {
  185. HKEY_LOCAL_MACHINE,
  186. "SYSTEM\\CurrentControlSet\\Services\\LmHosts\\Parameters",
  187. FALSE,
  188. LmHostsParameter_Values
  189. };
  190. CONST TR_VALUE_DESCRIPTOR NetbtInterface_Values [] =
  191. {
  192. TRV_DEL(NULL, "EnableAdapterDomainNameRegistration")
  193. TRV_MSZ(NULL, "NameServerList", "")
  194. TRV_DW (NULL, "NetbiosOptions", 0)
  195. TRV_END()
  196. };
  197. CONST TR_KEY_DESCRIPTOR NetbtInterfaces =
  198. {
  199. HKEY_LOCAL_MACHINE,
  200. "SYSTEM\\CurrentControlSet\\Services\\Netbt\\Parameters\\Interfaces",
  201. TRUE,
  202. NetbtInterface_Values
  203. };
  204. CONST TR_VALUE_DESCRIPTOR NetbtParameter_Values [] =
  205. {
  206. TRV_DEL(NULL, "BacklogIncrement")
  207. TRV_DW (NULL, "BcastNameQueryCount", 3)
  208. TRV_DW (NULL, "BcastQueryTimeout", 750)
  209. TRV_DEL(NULL, "BroadcastAddress")
  210. TRV_DEL(NULL, "CachePerAdapterEnabled")
  211. TRV_DW (NULL, "CacheTimeout", 600000)
  212. TRV_DEL(NULL, "ConnectOnRequestedInterfaceOnly")
  213. TRV_DEL(NULL, "EnableDns")
  214. TRV_DEL(NULL, "EnableLmhosts")
  215. TRV_DEL(NULL, "EnableProxy")
  216. TRV_DEL(NULL, "EnableProxyRegCheck")
  217. TRV_DEL(NULL, "InitialRefreshT.O.")
  218. TRV_DEL(NULL, "LmhostsTimeout")
  219. TRV_DEL(NULL, "MaxConnBackLog")
  220. TRV_DEL(NULL, "MaxDgramBuffering")
  221. TRV_DEL(NULL, "MaxPreloadEntries")
  222. TRV_DEL(NULL, "MinimumFreeLowerConnections")
  223. TRV_DEL(NULL, "MinimumRefreshSleepTime")
  224. TRV_DW (NULL, "NameServerPort", 137)
  225. TRV_DW (NULL, "NameSrvQueryCount", 3)
  226. TRV_DW (NULL, "NameSrvQueryTimeout", 1500)
  227. TRV_SZ (NULL, "NbProvider", "_tcp")
  228. TRV_DEL(NULL, "NodeType")
  229. TRV_DEL(NULL, "NoNameReleaseOnDemand")
  230. TRV_DEL(NULL, "RandomAdapter")
  231. TRV_DEL(NULL, "RefreshOpCode")
  232. TRV_DEL(NULL, "ScopeId")
  233. TRV_DW (NULL, "SessionKeepAlive", 3600000)
  234. TRV_DEL(NULL, "SingleResponse")
  235. TRV_DW (NULL, "Size/Small/Medium/Large", 1)
  236. TRV_DEL(NULL, "SmbDeviceEnabled")
  237. TRV_SZ (NULL, "TransportBindName", "\\Device\\")
  238. TRV_DEL(NULL, "TryAllIpAddrs")
  239. TRV_DEL(NULL, "TryAllNameServers")
  240. TRV_DEL(NULL, "UseDnsOnlyForNameResolutions")
  241. TRV_DEL(NULL, "WinsDownTimeout")
  242. TRV_END()
  243. };
  244. CONST TR_KEY_DESCRIPTOR NetbtParameters =
  245. {
  246. HKEY_LOCAL_MACHINE,
  247. "SYSTEM\\CurrentControlSet\\Services\\Netbt\\Parameters",
  248. FALSE,
  249. NetbtParameter_Values
  250. };
  251. CONST TR_VALUE_DESCRIPTOR NlaParameter_Values [] =
  252. {
  253. TRV_ESZ(NULL, "ServiceDll", "%SystemRoot%\\System32\\mswsock.dll")
  254. TRV_END()
  255. };
  256. CONST TR_KEY_DESCRIPTOR NlaParameters =
  257. {
  258. HKEY_LOCAL_MACHINE,
  259. "SYSTEM\\CurrentControlSet\\Services\\Nla\\Parameters",
  260. FALSE,
  261. NlaParameter_Values
  262. };
  263. CONST TR_VALUE_DESCRIPTOR TcpipInterface_Values [] =
  264. {
  265. TRV_DW_CA (NULL, "AddressType", 0)
  266. TRV_MSZ (NULL, "DefaultGateway", "")
  267. TRV_MSZ_CA(NULL, "DefaultGatewayMetric", "")
  268. TRV_DW_CA (NULL, "DisableDynamicUpdate", 0)
  269. TRV_DEL (NULL, "DisableReverseAddressRegistrations")
  270. TRV_DW_CD (NULL, "DontAddDefaultGateway", 0)
  271. TRV_DW_CV (NULL, "EnableDhcp", 0, 1)
  272. TRV_MSZ (NULL, "IpAddress", "0.0.0.0\0")
  273. TRV_DEL (NULL, "IpAutoconfigurationAddress")
  274. TRV_DEL (NULL, "IpAutoconfigurationEnabled")
  275. TRV_DEL (NULL, "IpAutoconfigurationMask")
  276. TRV_DEL (NULL, "IpAutoconfigurationSeed")
  277. TRV_DEL (NULL, "IpAutoconfigurationSubnet")
  278. TRV_DEL (NULL, "MaxForwardPending")
  279. TRV_DEL (NULL, "Mtu")
  280. TRV_SZ_CA (NULL, "NameServer", "")
  281. TRV_DEL (NULL, "PerformRouterDiscovery")
  282. TRV_DEL (NULL, "PerformRouterDiscoveryBackup")
  283. TRV_DEL (NULL, "PptpFiltering")
  284. TRV_MSZ_CA(NULL, "RawIpAllowedProtocols", "")
  285. TRV_DEL (NULL, "SolicitationAddressBcast")
  286. TRV_MSZ (NULL, "SubnetMask", "0.0.0.0\0")
  287. TRV_MSZ_CA(NULL, "TcpAllowedPorts", "")
  288. TRV_DEL (NULL, "TcpDelAckTicks")
  289. TRV_DEL (NULL, "TcpInitialRtt")
  290. TRV_DEL (NULL, "TcpWindowSize")
  291. TRV_DEL (NULL, "TypeOfInterface")
  292. TRV_MSZ_CA(NULL, "UdpAllowedPorts", "")
  293. TRV_DW (NULL, "UseZeroBroadcast", 0)
  294. TRV_END ()
  295. };
  296. CONST TR_KEY_DESCRIPTOR TcpipInterfaces =
  297. {
  298. HKEY_LOCAL_MACHINE,
  299. "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces",
  300. TRUE,
  301. TcpipInterface_Values,
  302. "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters",
  303. };
  304. CONST TR_VALUE_DESCRIPTOR TcpipParameter_Values [] =
  305. {
  306. TRV_DEL(NULL, "AllowUnqualifiedQuery")
  307. TRV_DEL(NULL, "AllowUserRawAccess")
  308. TRV_DEL(NULL, "ArpAlwaysSourceRoute")
  309. TRV_DEL(NULL, "ArpCacheLife")
  310. TRV_DEL(NULL, "ArpCacheMinReferencedLife")
  311. TRV_DEL(NULL, "ArpRetryCount")
  312. TRV_DEL(NULL, "ArpTrSingleRoute")
  313. TRV_DEL(NULL, "ArpUseEtherSnap")
  314. TRV_ESZ(NULL, "DatabasePath", "%SystemRoot%\\System32\\drivers\\etc")
  315. TRV_DEL(NULL, "DefaultRegistrationTtl")
  316. TRV_DEL(NULL, "DefaultTosValue")
  317. TRV_DEL(NULL, "DefaultTtl")
  318. TRV_DEL(NULL, "DisableDhcpMediaSense")
  319. TRV_DEL(NULL, "DisableDynamicUpdate")
  320. TRV_DEL(NULL, "DisableIpSourceRouting")
  321. TRV_DEL(NULL, "DisableMediaSenseEventLog")
  322. TRV_DEL(NULL, "DisableReplaceAddressesInConflicts")
  323. TRV_DEL(NULL, "DisableTaskOffload")
  324. TRV_DEL(NULL, "DisableUserTosSetting")
  325. TRV_DEL(NULL, "DisjointNameSpace")
  326. TRV_DEL(NULL, "DontAddDefaultGatewayDefault")
  327. TRV_DEL(NULL, "DnsQueryTimeouts")
  328. TRV_DEL(NULL, "EnableAddrMaskReply")
  329. TRV_DEL(NULL, "EnableBcastArpReply")
  330. TRV_DEL(NULL, "EnableDeadGwDetect")
  331. TRV_DEL(NULL, "EnableFastRouteLookup")
  332. TRV_DEL(NULL, "EnableIcmpRedirect")
  333. TRV_DEL(NULL, "EnableMulticastForwarding")
  334. TRV_DEL(NULL, "EnablePmtuBhDetect")
  335. TRV_DEL(NULL, "EnablePmtuDiscovery")
  336. TRV_DEL(NULL, "EnableSecurityFilters")
  337. TRV_DEL(NULL, "FfpControlFlags")
  338. TRV_DEL(NULL, "FfpFastForwardingCacheSize")
  339. TRV_DW (NULL, "ForwardBroadcasts", 0)
  340. TRV_DEL(NULL, "ForwardBufferMemory")
  341. TRV_DEL(NULL, "GlobalMaxTcpWindowSize")
  342. TRV_DEL(NULL, "IgmpLevel")
  343. TRV_DEL(NULL, "IpAutoconfigurationEnabled")
  344. TRV_DEL(NULL, "IpAutoconfigurationMask")
  345. TRV_DEL(NULL, "IpAutoconfigurationSeed")
  346. TRV_DW (NULL, "IpEnableRouter", 0)
  347. TRV_DEL(NULL, "IpEnableRouterBackup")
  348. TRV_DEL(NULL, "KeepAliveInterval")
  349. TRV_DEL(NULL, "KeepAliveTime")
  350. TRV_SZ (NULL, "NameServer", "")
  351. TRV_DEL(NULL, "MaxForwardBufferMemory")
  352. TRV_DEL(NULL, "MaxFreeTWTcbs")
  353. TRV_DEL(NULL, "MaxFreeTcbs")
  354. TRV_DEL(NULL, "MaxHashTableSize")
  355. TRV_DEL(NULL, "MaxNormLookupMemory")
  356. TRV_DEL(NULL, "MaxNumForwardPackets")
  357. TRV_DEL(NULL, "MaxUserPort")
  358. TRV_DEL(NULL, "NumForwardPackets")
  359. TRV_DEL(NULL, "NumTcbTablePartitions")
  360. TRV_DEL(NULL, "PptpTcpMaxDataRetransmissions")
  361. TRV_DEL(NULL, "PrioritizeRecordData")
  362. TRV_DEL(NULL, "QueryIpMatching")
  363. TRV_DEL(NULL, "SackOpts")
  364. TRV_DEL(NULL, "SearchList")
  365. TRV_DEL(NULL, "SynAttackProtect")
  366. TRV_DEL(NULL, "Tcp1323Opts")
  367. TRV_DEL(NULL, "TcpMaxConnectResponseRetransmissions")
  368. TRV_DEL(NULL, "TcpMaxConnectRetransmissions")
  369. TRV_DEL(NULL, "TcpMaxDataRetransmissions")
  370. TRV_DEL(NULL, "TcpMaxDupAcks")
  371. TRV_DEL(NULL, "TcpMaxHalfOpen")
  372. TRV_DEL(NULL, "TcpMaxHalfOpenRetried")
  373. TRV_DEL(NULL, "TcpMaxPortsExhausted")
  374. TRV_DEL(NULL, "TcpMaxSendFree")
  375. TRV_DEL(NULL, "TcpNumConnections")
  376. TRV_DEL(NULL, "TcpTimedWaitDelay")
  377. TRV_DEL(NULL, "TcpUseRfc1122UrgentPointer")
  378. TRV_DEL(NULL, "TcpWindowSize")
  379. TRV_DEL(NULL, "TrFunctionalMcastAddress")
  380. TRV_DEL(NULL, "UpdateSecurityLevel")
  381. TRV_DEL(NULL, "UseDomainNameDevolution")
  382. TRV_DW ("Winsock", "UseDelayedAcceptance", 0)
  383. TRV_END()
  384. };
  385. CONST TR_KEY_DESCRIPTOR TcpipParameters =
  386. {
  387. HKEY_LOCAL_MACHINE,
  388. "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
  389. FALSE,
  390. TcpipParameter_Values
  391. };
  392. CONST TR_VALUE_DESCRIPTOR TcpipPerformance_Values [] =
  393. {
  394. TRV_SZ (NULL, "Close", "CloseTcpIpPerformanceData")
  395. TRV_SZ (NULL, "Collect", "CollectTcpIpPerformanceData")
  396. TRV_SZ (NULL, "Library", "Perfctrs.dll")
  397. TRV_SZ (NULL, "Open", "OpenTcpIpPerformanceData")
  398. TRV_SZ (NULL, "Object List", "502 510 546 582 638 658")
  399. TRV_END()
  400. };
  401. CONST TR_KEY_DESCRIPTOR TcpipPerformance =
  402. {
  403. HKEY_LOCAL_MACHINE,
  404. "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Performance",
  405. FALSE,
  406. TcpipPerformance_Values
  407. };
  408. CONST TR_VALUE_DESCRIPTOR TcpipServiceProvider_Values [] =
  409. {
  410. TRV_DW (NULL, "Class", 8)
  411. TRV_DW (NULL, "DnsPriority", 2000)
  412. TRV_DW (NULL, "HostsPriority", 500)
  413. TRV_DW (NULL, "LocalPriority", 499)
  414. TRV_DW (NULL, "NetbtPriority", 2001)
  415. TRV_SZ (NULL, "Name", "TCP/IP")
  416. TRV_ESZ(NULL, "ProviderPath", "%SystemRoot%\\System32\\wsock32.dll")
  417. TRV_END()
  418. };
  419. CONST TR_KEY_DESCRIPTOR TcpipServiceProvider =
  420. {
  421. HKEY_LOCAL_MACHINE,
  422. "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\ServiceProvider",
  423. FALSE,
  424. TcpipServiceProvider_Values
  425. };
  426. CONST TR_KEY_DESCRIPTOR* TrRepairSet [] =
  427. {
  428. &DhcpParameterOptions,
  429. &DhcpParameters,
  430. &DnscacheParameters,
  431. &LmHostsParameters,
  432. &NetbtInterfaces,
  433. &NetbtParameters,
  434. &NlaParameters,
  435. &TcpipInterfaces,
  436. &TcpipParameters,
  437. &TcpipPerformance,
  438. &TcpipServiceProvider,
  439. NULL
  440. };
  441. #define SAM_DESIRED KEY_READ | KEY_WRITE | DELETE
  442. typedef enum _TR_LOG_ACTION {
  443. TR_ADDED,
  444. TR_DELETED,
  445. TR_RESET,
  446. } TR_LOG_ACTION;
  447. CONST PCSTR LogActionPrefix [] = {
  448. "added ",
  449. "deleted",
  450. "reset ",
  451. };
  452. typedef struct _TR_REPAIR_CONTEXT {
  453. HANDLE Heap;
  454. FILE *LogFile;
  455. PBYTE RegData;
  456. ULONG RegDataSize;
  457. CHAR EnumKeyName [MAX_PATH];
  458. } TR_REPAIR_CONTEXT, *PTR_REPAIR_CTX;
  459. BOOL
  460. TrInitializeRepairContext(
  461. IN PTR_REPAIR_CTX Ctx,
  462. IN FILE *LogFile
  463. )
  464. {
  465. ZeroMemory(Ctx, sizeof(TR_REPAIR_CONTEXT));
  466. Ctx->Heap = GetProcessHeap();
  467. Ctx->LogFile = LogFile;
  468. Ctx->RegDataSize = 1024;
  469. Ctx->RegData = HeapAlloc(Ctx->Heap, 0, Ctx->RegDataSize);
  470. *Ctx->EnumKeyName = 0;
  471. return (Ctx->RegData != NULL);
  472. }
  473. VOID
  474. TrCleanupRepairContext(
  475. IN PTR_REPAIR_CTX Ctx
  476. )
  477. {
  478. if (Ctx->RegData != NULL) {
  479. HeapFree(Ctx->Heap, 0, Ctx->RegData);
  480. Ctx->RegData = NULL;
  481. }
  482. }
  483. VOID
  484. TrLogAction(
  485. IN TR_LOG_ACTION Action,
  486. IN PTR_REPAIR_CTX Ctx,
  487. IN CONST TR_KEY_DESCRIPTOR *Kd,
  488. IN CONST TR_VALUE_DESCRIPTOR *Vd
  489. )
  490. {
  491. fprintf(Ctx->LogFile, "%s %s\\",
  492. LogActionPrefix[Action], Kd->ParentKeyName);
  493. if (Vd->SubKeyName != NULL) {
  494. fprintf(Ctx->LogFile, "%s\\", Vd->SubKeyName);
  495. }
  496. if (Kd->EnumKey) {
  497. fprintf(Ctx->LogFile, "%s\\", Ctx->EnumKeyName);
  498. }
  499. fprintf(Ctx->LogFile, "%s\n", Vd->ValueName);
  500. //
  501. // Show the value we are replacing.
  502. //
  503. if (TR_RESET == Action) {
  504. switch (Vd->RegType) {
  505. case REG_DWORD:
  506. fprintf(Ctx->LogFile, " old REG_DWORD = %d\n\n", *(PULONG)Ctx->RegData);
  507. break;
  508. case REG_EXPAND_SZ:
  509. fprintf(Ctx->LogFile, " old REG_EXPAND_SZ = %s\n\n", (PCSTR)Ctx->RegData);
  510. break;
  511. case REG_MULTI_SZ:
  512. {
  513. PCSTR Msz = (PCSTR)Ctx->RegData;
  514. fprintf(Ctx->LogFile, " old REG_MULTI_SZ =\n");
  515. if (*Msz) {
  516. while (*Msz) {
  517. fprintf(Ctx->LogFile, " %s\n", Msz);
  518. Msz += strlen(Msz) + 1;
  519. }
  520. } else {
  521. fprintf(Ctx->LogFile, " <empty>\n");
  522. }
  523. fprintf(Ctx->LogFile, "\n");
  524. break;
  525. }
  526. case REG_SZ:
  527. fprintf(Ctx->LogFile, " old REG_SZ = %s\n\n", (PCSTR)Ctx->RegData);
  528. break;
  529. default:
  530. break;
  531. }
  532. }
  533. }
  534. LONG
  535. TrReadRegData(
  536. IN PTR_REPAIR_CTX Ctx,
  537. IN HKEY Key,
  538. IN CONST TR_VALUE_DESCRIPTOR *Vd,
  539. OUT PULONG ReturnedSize
  540. )
  541. {
  542. LONG Error;
  543. ULONG Type, Size;
  544. *ReturnedSize = 0;
  545. Size = Ctx->RegDataSize;
  546. Error = RegQueryValueExA(Key, Vd->ValueName, NULL, &Type,
  547. Ctx->RegData, &Size);
  548. if (ERROR_MORE_DATA == Error) {
  549. HeapFree(Ctx->Heap, 0, Ctx->RegData);
  550. Ctx->RegDataSize = (Size + 63) & ~63;
  551. Ctx->RegData = HeapAlloc(Ctx->Heap, 0, Ctx->RegDataSize);
  552. if (Ctx->RegData != NULL) {
  553. Size = Ctx->RegDataSize;
  554. Error = RegQueryValueExA(Key, Vd->ValueName, NULL, &Type,
  555. Ctx->RegData, &Size);
  556. if (NOERROR != Error) {
  557. fprintf(Ctx->LogFile,
  558. " RegQueryValueEx still failed. error = %d\n",
  559. Error);
  560. } else {
  561. *ReturnedSize = Size;
  562. }
  563. } else {
  564. Error = ERROR_NOT_ENOUGH_MEMORY;
  565. }
  566. } else if (NOERROR == Error) {
  567. *ReturnedSize = Size;
  568. }
  569. return Error;
  570. }
  571. VOID
  572. TrSetRegData(
  573. IN HKEY Key,
  574. IN CONST TR_VALUE_DESCRIPTOR *Vd,
  575. IN BOOLEAN ConditionalKeyPresent
  576. )
  577. {
  578. CONST BYTE *Data;
  579. ConditionalKeyPresent &= (Vd->Conditional != COND_NONE);
  580. if (REG_DWORD == Vd->RegType) {
  581. Data = (CONST BYTE*)((ConditionalKeyPresent)? &Vd->ConditionalDataValue : &Vd->DataValue);
  582. } else {
  583. Data = (ConditionalKeyPresent)? Vd->ConditionalDataPointer : Vd->DataPointer;
  584. }
  585. RegSetValueExA(Key, Vd->ValueName, 0, Vd->RegType, Data, Vd->DataSize);
  586. }
  587. BOOLEAN
  588. TrKeyShouldExist(
  589. IN CONST TR_VALUE_DESCRIPTOR *Vd,
  590. IN BOOLEAN ConditionalKeyPresent
  591. )
  592. {
  593. if (REG_DELETE == Vd->RegType) {
  594. return FALSE;
  595. }
  596. if ((Vd->Conditional == COND_ADD) && !ConditionalKeyPresent) {
  597. return FALSE;
  598. }
  599. if ((Vd->Conditional == COND_DELETE) && ConditionalKeyPresent) {
  600. return FALSE;
  601. }
  602. return TRUE;
  603. }
  604. VOID
  605. TrProcessOpenKey(
  606. IN PTR_REPAIR_CTX Ctx,
  607. IN HKEY ParentKey,
  608. IN BOOLEAN ConditionalKeyPresent,
  609. IN CONST TR_KEY_DESCRIPTOR *Kd
  610. )
  611. {
  612. LONG Error;
  613. ULONG i, Size;
  614. CONST TR_VALUE_DESCRIPTOR *Vd, *PrevVd;
  615. HKEY SubKey, UseKey;
  616. PrevVd = NULL;
  617. SubKey = INVALID_HANDLE_VALUE;
  618. for (i = 0; Kd->Value[i].ValueName != NULL; i++) {
  619. Vd = &Kd->Value[i];
  620. if (Vd->SubKeyName == NULL) {
  621. UseKey = ParentKey;
  622. }
  623. //
  624. // Open a subkey if needed, and only if its not the same as
  625. // the one already open.
  626. //
  627. else if (((PrevVd == NULL) || (Vd->SubKeyName != PrevVd->SubKeyName))) {
  628. if (SubKey != INVALID_HANDLE_VALUE) {
  629. RegCloseKey(SubKey);
  630. }
  631. Error = RegOpenKeyExA(ParentKey, Vd->SubKeyName, 0,
  632. SAM_DESIRED, &SubKey);
  633. if (NOERROR == Error) {
  634. UseKey = SubKey;
  635. } else {
  636. SubKey = INVALID_HANDLE_VALUE;
  637. }
  638. }
  639. Error = TrReadRegData(Ctx, UseKey, Vd, &Size);
  640. if (ERROR_FILE_NOT_FOUND == Error) {
  641. if (TrKeyShouldExist(Vd, ConditionalKeyPresent)) {
  642. //
  643. // The value should exist, so set its default value.
  644. //
  645. TrSetRegData(UseKey, Vd, ConditionalKeyPresent);
  646. TrLogAction(TR_ADDED, Ctx, Kd, Vd);
  647. }
  648. } else if (NOERROR == Error) {
  649. //
  650. // The value exists and we read its data.
  651. //
  652. if (!TrKeyShouldExist(Vd, ConditionalKeyPresent)) {
  653. //
  654. // Need to delete the existing value.
  655. //
  656. RegDeleteValueA(UseKey, Vd->ValueName);
  657. TrLogAction(TR_DELETED, Ctx, Kd, Vd);
  658. } else {
  659. BOOL MisCompare = TRUE;
  660. //
  661. // Compare the value we read with the default value and reset
  662. // it if it is different.
  663. //
  664. if (Size == Vd->DataSize) {
  665. if (REG_DWORD == Vd->RegType) {
  666. MisCompare = (*(PULONG)Ctx->RegData != ((ConditionalKeyPresent && (Vd->Conditional != COND_NONE))? Vd->ConditionalDataValue : Vd->DataValue));
  667. } else {
  668. MisCompare = memcmp(Ctx->RegData, (ConditionalKeyPresent && (Vd->Conditional != COND_NONE))? Vd->ConditionalDataPointer : Vd->DataPointer, Size);
  669. }
  670. }
  671. if (MisCompare) {
  672. TrSetRegData(UseKey, Vd, ConditionalKeyPresent);
  673. TrLogAction(TR_RESET, Ctx, Kd, Vd);
  674. }
  675. }
  676. } else {
  677. fprintf(Ctx->LogFile, "\nerror reading registry value (%s) (%d)\n", Vd->ValueName, Error);
  678. }
  679. PrevVd = Vd;
  680. }
  681. if (SubKey != INVALID_HANDLE_VALUE) {
  682. RegCloseKey(SubKey);
  683. }
  684. }
  685. VOID
  686. TrProcessKey(
  687. IN PTR_REPAIR_CTX Ctx,
  688. IN CONST TR_KEY_DESCRIPTOR *Kd
  689. )
  690. {
  691. LONG Error;
  692. HKEY ParentKey, ConditionalParentKey;
  693. BOOLEAN ConditionalKeyPresent;
  694. Error = RegOpenKeyExA(Kd->RootKey, Kd->ConditionalParentKeyName, 0,
  695. SAM_DESIRED, &ConditionalParentKey);
  696. if (NOERROR != Error) {
  697. ConditionalParentKey = NULL;
  698. }
  699. Error = RegOpenKeyExA(Kd->RootKey, Kd->ParentKeyName, 0,
  700. SAM_DESIRED, &ParentKey);
  701. if (NOERROR == Error) {
  702. if (Kd->EnumKey) {
  703. ULONG i;
  704. ULONG EnumKeyNameLen;
  705. FILETIME LastWriteTime;
  706. HKEY SubKey, ConditionalSubKey;
  707. for (i = 0; NOERROR == Error; i++) {
  708. EnumKeyNameLen = sizeof(Ctx->EnumKeyName);
  709. Error = RegEnumKeyExA(ParentKey, i, Ctx->EnumKeyName, &EnumKeyNameLen,
  710. NULL, NULL, NULL, &LastWriteTime);
  711. if (NOERROR != Error) {
  712. if (ERROR_NO_MORE_ITEMS != Error) {
  713. fprintf(Ctx->LogFile, "enum error = %d (index = %d)\n",
  714. Error, i);
  715. }
  716. break;
  717. }
  718. ConditionalKeyPresent = FALSE;
  719. if (ConditionalParentKey) {
  720. Error = RegOpenKeyExA(ConditionalParentKey,
  721. Ctx->EnumKeyName, 0,
  722. SAM_DESIRED, &ConditionalSubKey);
  723. if (NO_ERROR == Error) {
  724. RegCloseKey(ConditionalSubKey);
  725. ConditionalKeyPresent = TRUE;
  726. }
  727. }
  728. Error = RegOpenKeyExA(ParentKey, Ctx->EnumKeyName, 0,
  729. SAM_DESIRED, &SubKey);
  730. if (NOERROR == Error) {
  731. TrProcessOpenKey(Ctx, SubKey, ConditionalKeyPresent, Kd);
  732. RegCloseKey(SubKey);
  733. }
  734. }
  735. } else {
  736. TrProcessOpenKey(Ctx, ParentKey, FALSE, Kd);
  737. }
  738. RegCloseKey(ParentKey);
  739. }
  740. if (ConditionalParentKey) {
  741. RegCloseKey(ConditionalParentKey);
  742. }
  743. }
  744. VOID
  745. TrProcessSet(
  746. IN PTR_REPAIR_CTX Ctx,
  747. IN CONST TR_KEY_DESCRIPTOR *Set[]
  748. )
  749. {
  750. ULONG i;
  751. //
  752. // Process each TR_KEY_DESCRIPTOR element in the set.
  753. //
  754. for (i = 0; Set[i] != NULL; i++) {
  755. TrProcessKey(Ctx, Set[i]);
  756. }
  757. }
  758. DWORD
  759. TrRepair(
  760. FILE* LogFile
  761. )
  762. {
  763. TR_REPAIR_CONTEXT Ctx;
  764. if (TrInitializeRepairContext(&Ctx, LogFile)) {
  765. TrProcessSet(&Ctx, TrRepairSet);
  766. NetCfgDiagRepairRegistryBindings(LogFile);
  767. TrCleanupRepairContext(&Ctx);
  768. }
  769. return NOERROR;
  770. }