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.

2931 lines
101 KiB

  1. /*++
  2. Copyright(c) 1998,99 Microsoft Corporation
  3. Module Name:
  4. params.cpp
  5. Abstract:
  6. Windows Load Balancing Service (WLBS)
  7. API - registry parameters support
  8. Author:
  9. kyrilf
  10. --*/
  11. #include "precomp.h"
  12. #include "cluster.h"
  13. #include "control.h"
  14. #include "param.h"
  15. #include "debug.h"
  16. #include "params.tmh" // for event tracing
  17. extern HINSTANCE g_hInstCtrl; // Global variable for the dll instance, defined in control.cpp
  18. HKEY WINAPI RegOpenWlbsSetting(const GUID& AdapterGuid, bool fReadOnly)
  19. {
  20. WCHAR reg_path [PARAMS_MAX_STRING_SIZE];
  21. WCHAR szAdapterGuid[128];
  22. StringFromGUID2(AdapterGuid, szAdapterGuid,
  23. sizeof(szAdapterGuid)/sizeof(szAdapterGuid[0]) );
  24. swprintf (reg_path, L"SYSTEM\\CurrentControlSet\\Services\\WLBS\\Parameters\\Interface\\%s",
  25. szAdapterGuid);
  26. HKEY hKey = NULL;
  27. RegOpenKeyEx (HKEY_LOCAL_MACHINE, reg_path, 0L,
  28. fReadOnly? KEY_READ : KEY_WRITE, & hKey);
  29. return hKey;
  30. }
  31. //+----------------------------------------------------------------------------
  32. //
  33. // Function: TransformOldPortRulesToNew
  34. //
  35. // Description: Transforms port rules contained in structures without the virtual
  36. // ip address into the new ones that do
  37. //
  38. // Arguments: Array of Old Port Rules, Array of New Port Rules, Length of Array
  39. //
  40. // Returns: void
  41. //
  42. // History: KarthicN, Created on 3/19/01
  43. //
  44. //+----------------------------------------------------------------------------
  45. void TransformOldPortRulesToNew(PWLBS_OLD_PORT_RULE p_old_port_rules,
  46. PWLBS_PORT_RULE p_new_port_rules,
  47. DWORD num_rules)
  48. {
  49. if (num_rules == 0)
  50. return;
  51. while(num_rules--)
  52. {
  53. lstrcpy(p_new_port_rules->virtual_ip_addr, CVY_DEF_ALL_VIP);
  54. p_new_port_rules->start_port = p_old_port_rules->start_port;
  55. p_new_port_rules->end_port = p_old_port_rules->end_port;
  56. #ifdef WLBSAPI_INTERNAL_ONLY
  57. p_new_port_rules->code = p_old_port_rules->code;
  58. #else
  59. p_new_port_rules->Private1 = p_old_port_rules->Private1;
  60. #endif
  61. p_new_port_rules->mode = p_old_port_rules->mode;
  62. p_new_port_rules->protocol = p_old_port_rules->protocol;
  63. #ifdef WLBSAPI_INTERNAL_ONLY
  64. p_new_port_rules->valid = p_old_port_rules->valid;
  65. #else
  66. p_new_port_rules->Private2 = p_old_port_rules->Private2;
  67. #endif
  68. switch (p_new_port_rules->mode)
  69. {
  70. case CVY_MULTI :
  71. p_new_port_rules->mode_data.multi.equal_load = p_old_port_rules->mode_data.multi.equal_load;
  72. p_new_port_rules->mode_data.multi.affinity = p_old_port_rules->mode_data.multi.affinity;
  73. p_new_port_rules->mode_data.multi.load = p_old_port_rules->mode_data.multi.load;
  74. break;
  75. case CVY_SINGLE :
  76. p_new_port_rules->mode_data.single.priority = p_old_port_rules->mode_data.single.priority;
  77. break;
  78. default:
  79. break;
  80. }
  81. p_old_port_rules++;
  82. p_new_port_rules++;
  83. }
  84. return;
  85. }
  86. /* Open the bi-directional affinity teaming registry key for a specified adapter. */
  87. HKEY WINAPI RegOpenWlbsBDASettings (const GUID& AdapterGuid, bool fReadOnly) {
  88. WCHAR reg_path[PARAMS_MAX_STRING_SIZE];
  89. WCHAR szAdapterGuid[128];
  90. HKEY hKey = NULL;
  91. DWORD dwRet;
  92. StringFromGUID2(AdapterGuid, szAdapterGuid, sizeof(szAdapterGuid)/sizeof(szAdapterGuid[0]));
  93. swprintf(reg_path, L"SYSTEM\\CurrentControlSet\\Services\\WLBS\\Parameters\\Interface\\%ls\\%ls", szAdapterGuid, CVY_NAME_BDA_TEAMING);
  94. dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg_path, 0L, fReadOnly ? KEY_READ : KEY_WRITE, &hKey);
  95. if (dwRet != ERROR_SUCCESS) {
  96. LOG_ERROR2("RegOpenWlbsBDASettings for %ls failed with error 0x%08x", szAdapterGuid, dwRet);
  97. return NULL;
  98. }
  99. return hKey;
  100. }
  101. /* Create the bi-directional affinity teaming registry key for a specified adapter. */
  102. HKEY WINAPI RegCreateWlbsBDASettings (const GUID& AdapterGuid) {
  103. WCHAR reg_path[PARAMS_MAX_STRING_SIZE];
  104. WCHAR szAdapterGuid[128];
  105. HKEY hKey = NULL;
  106. DWORD dwRet;
  107. DWORD disp;
  108. StringFromGUID2(AdapterGuid, szAdapterGuid, sizeof(szAdapterGuid)/sizeof(szAdapterGuid[0]));
  109. swprintf(reg_path, L"SYSTEM\\CurrentControlSet\\Services\\WLBS\\Parameters\\Interface\\%ls\\%ls", szAdapterGuid, CVY_NAME_BDA_TEAMING);
  110. dwRet = RegCreateKeyEx(HKEY_LOCAL_MACHINE, reg_path, 0L, L"", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &disp);
  111. if (dwRet != ERROR_SUCCESS) {
  112. LOG_ERROR2("RegCreateWlbsBDASettings for %ls failed with error 0x%08x", szAdapterGuid, dwRet);
  113. return NULL;
  114. }
  115. return hKey;
  116. }
  117. /* Delete the bi-directional affinity teaming registry key for a specified adapter. */
  118. bool WINAPI RegDeleteWlbsBDASettings (const GUID& AdapterGuid) {
  119. WCHAR reg_path[PARAMS_MAX_STRING_SIZE];
  120. WCHAR szAdapterGuid[128];
  121. DWORD dwRet;
  122. StringFromGUID2(AdapterGuid, szAdapterGuid, sizeof(szAdapterGuid)/sizeof(szAdapterGuid[0]));
  123. swprintf(reg_path, L"SYSTEM\\CurrentControlSet\\Services\\WLBS\\Parameters\\Interface\\%ls\\%ls", szAdapterGuid, CVY_NAME_BDA_TEAMING);
  124. dwRet = RegDeleteKey(HKEY_LOCAL_MACHINE, reg_path);
  125. if (dwRet != ERROR_SUCCESS) {
  126. LOG_ERROR2("RegDeleteWlbsBDASettings for %ls failed with error 0x%08x", szAdapterGuid, dwRet);
  127. return FALSE;
  128. }
  129. return TRUE;
  130. }
  131. //+----------------------------------------------------------------------------
  132. //
  133. // Function: ParamReadReg
  134. //
  135. // Description: Read cluster settings from registry
  136. //
  137. // Arguments: const GUID& AdapterGuid - IN, Adapter guid
  138. // PWLBS_REG_PARAMS paramp - OUT Registry parameters
  139. // bool fUpgradeFromWin2k, whether this is a upgrade from Win2k
  140. // or earlier version
  141. //
  142. // Returns: bool - true if succeeded
  143. //
  144. // History: fengsun Created Header 3/9/00
  145. //
  146. //+----------------------------------------------------------------------------
  147. bool WINAPI ParamReadReg(const GUID& AdapterGuid,
  148. PWLBS_REG_PARAMS paramp, bool fUpgradeFromWin2k, bool *pfPortRulesInBinaryForm)
  149. {
  150. HKEY bda_key = NULL;
  151. HKEY key;
  152. LONG status;
  153. DWORD type;
  154. DWORD size;
  155. ULONG i, code;
  156. WLBS_PORT_RULE* rp;
  157. WCHAR reg_path [PARAMS_MAX_STRING_SIZE];
  158. memset (paramp, 0, sizeof (*paramp));
  159. //
  160. // For win2k or NT4, only one cluster is supported, there is no per adapter settings
  161. //
  162. if (fUpgradeFromWin2k)
  163. {
  164. swprintf (reg_path, L"SYSTEM\\CurrentControlSet\\Services\\WLBS\\Parameters");
  165. status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, reg_path, 0L,
  166. KEY_QUERY_VALUE, & key);
  167. if (status != ERROR_SUCCESS)
  168. {
  169. return false;
  170. }
  171. }
  172. else
  173. {
  174. key = RegOpenWlbsSetting(AdapterGuid, true);
  175. if (key == NULL)
  176. {
  177. return false;
  178. }
  179. }
  180. swprintf (reg_path, L"%ls", CVY_NAME_INSTALL_DATE);
  181. size = sizeof (paramp -> install_date);
  182. status = RegQueryValueEx (key, reg_path, 0L, & type,
  183. (LPBYTE) & paramp -> install_date, & size);
  184. if (status != ERROR_SUCCESS)
  185. paramp -> install_date = 0;
  186. swprintf (reg_path, L"%ls", CVY_NAME_VERIFY_DATE);
  187. size = sizeof (paramp -> i_verify_date);
  188. status = RegQueryValueEx (key, reg_path, 0L, & type,
  189. (LPBYTE) & paramp -> i_verify_date, & size);
  190. if (status != ERROR_SUCCESS)
  191. paramp -> i_verify_date = 0;
  192. swprintf (reg_path, L"%ls", CVY_NAME_VERSION);
  193. size = sizeof (paramp -> i_parms_ver);
  194. status = RegQueryValueEx (key, reg_path, 0L, & type,
  195. (LPBYTE) & paramp -> i_parms_ver, & size);
  196. if (status != ERROR_SUCCESS)
  197. paramp -> i_parms_ver = CVY_DEF_VERSION;
  198. swprintf (reg_path, L"%ls", CVY_NAME_VIRTUAL_NIC);
  199. size = sizeof (paramp -> i_virtual_nic_name);
  200. status = RegQueryValueEx (key, reg_path, 0L, & type,
  201. (LPBYTE) paramp -> i_virtual_nic_name, & size);
  202. if (status != ERROR_SUCCESS)
  203. paramp -> i_virtual_nic_name [0] = 0;
  204. /*
  205. swprintf (reg_path, L"%ls", CVY_NAME_CLUSTER_NIC);
  206. size = sizeof (paramp -> cluster_nic_name);
  207. status = RegQueryValueEx (key, reg_path, 0L, & type,
  208. (LPBYTE) paramp -> cluster_nic_name, & size);
  209. if (status != ERROR_SUCCESS)
  210. paramp -> cluster_nic_name [0] = 0;
  211. */
  212. swprintf (reg_path, L"%ls", CVY_NAME_HOST_PRIORITY);
  213. size = sizeof (paramp -> host_priority);
  214. status = RegQueryValueEx (key, reg_path, 0L, & type,
  215. (LPBYTE) & paramp -> host_priority, & size);
  216. if (status != ERROR_SUCCESS)
  217. paramp -> host_priority = CVY_DEF_HOST_PRIORITY;
  218. swprintf (reg_path, L"%ls", CVY_NAME_CLUSTER_MODE);
  219. size = sizeof (paramp -> cluster_mode);
  220. status = RegQueryValueEx (key, reg_path, 0L, & type,
  221. (LPBYTE) & paramp -> cluster_mode, & size);
  222. if (status != ERROR_SUCCESS)
  223. paramp -> cluster_mode = CVY_DEF_CLUSTER_MODE;
  224. swprintf (reg_path, L"%ls", CVY_NAME_NETWORK_ADDR);
  225. size = sizeof (paramp -> cl_mac_addr);
  226. status = RegQueryValueEx (key, reg_path, 0L, & type,
  227. (LPBYTE) paramp -> cl_mac_addr, & size);
  228. if (status != ERROR_SUCCESS)
  229. swprintf (paramp -> cl_mac_addr, L"%ls", CVY_DEF_NETWORK_ADDR);
  230. swprintf (reg_path, L"%ls", CVY_NAME_CL_IP_ADDR);
  231. size = sizeof (paramp -> cl_ip_addr);
  232. status = RegQueryValueEx (key, reg_path, 0L, & type,
  233. (LPBYTE) paramp -> cl_ip_addr, & size);
  234. if (status != ERROR_SUCCESS)
  235. swprintf (paramp -> cl_ip_addr, L"%ls", CVY_DEF_CL_IP_ADDR);
  236. swprintf (reg_path, L"%ls", CVY_NAME_CL_NET_MASK);
  237. size = sizeof (paramp -> cl_net_mask);
  238. status = RegQueryValueEx (key, reg_path, 0L, & type,
  239. (LPBYTE) paramp -> cl_net_mask, & size);
  240. if (status != ERROR_SUCCESS)
  241. swprintf (paramp -> cl_net_mask, L"%ls", CVY_DEF_CL_NET_MASK);
  242. swprintf (reg_path, L"%ls", CVY_NAME_DED_IP_ADDR);
  243. size = sizeof (paramp -> ded_ip_addr);
  244. status = RegQueryValueEx (key, reg_path, 0L, & type,
  245. (LPBYTE) paramp -> ded_ip_addr, & size);
  246. if (status != ERROR_SUCCESS)
  247. swprintf (paramp -> ded_ip_addr, L"%ls", CVY_DEF_DED_IP_ADDR);
  248. swprintf (reg_path, L"%ls", CVY_NAME_DED_NET_MASK);
  249. size = sizeof (paramp -> ded_net_mask);
  250. status = RegQueryValueEx (key, reg_path, 0L, & type,
  251. (LPBYTE) paramp -> ded_net_mask, & size);
  252. if (status != ERROR_SUCCESS)
  253. swprintf (paramp -> ded_net_mask, L"%ls", CVY_DEF_DED_NET_MASK);
  254. swprintf (reg_path, L"%ls", CVY_NAME_DOMAIN_NAME);
  255. size = sizeof (paramp -> domain_name);
  256. status = RegQueryValueEx (key, reg_path, 0L, & type,
  257. (LPBYTE) paramp -> domain_name, & size);
  258. if (status != ERROR_SUCCESS)
  259. swprintf (paramp -> domain_name, L"%ls", CVY_DEF_DOMAIN_NAME);
  260. swprintf (reg_path, L"%ls", CVY_NAME_ALIVE_PERIOD);
  261. size = sizeof (paramp -> alive_period);
  262. status = RegQueryValueEx (key, reg_path, 0L, & type,
  263. (LPBYTE) & paramp -> alive_period, & size);
  264. if (status != ERROR_SUCCESS)
  265. paramp -> alive_period = CVY_DEF_ALIVE_PERIOD;
  266. swprintf (reg_path, L"%ls", CVY_NAME_ALIVE_TOLER);
  267. size = sizeof (paramp -> alive_tolerance);
  268. status = RegQueryValueEx (key, reg_path, 0L, & type,
  269. (LPBYTE) & paramp -> alive_tolerance, & size);
  270. if (status != ERROR_SUCCESS)
  271. paramp -> alive_tolerance = CVY_DEF_ALIVE_TOLER;
  272. swprintf (reg_path, L"%ls", CVY_NAME_NUM_ACTIONS);
  273. size = sizeof (paramp -> num_actions);
  274. status = RegQueryValueEx (key, reg_path, 0L, & type,
  275. (LPBYTE) & paramp -> num_actions, & size);
  276. if (status != ERROR_SUCCESS)
  277. paramp -> num_actions = CVY_DEF_NUM_ACTIONS;
  278. swprintf (reg_path, L"%ls", CVY_NAME_NUM_PACKETS);
  279. size = sizeof (paramp -> num_packets);
  280. status = RegQueryValueEx (key, reg_path, 0L, & type,
  281. (LPBYTE) & paramp -> num_packets, & size);
  282. if (status != ERROR_SUCCESS)
  283. paramp -> num_packets = CVY_DEF_NUM_PACKETS;
  284. swprintf (reg_path, L"%ls", CVY_NAME_NUM_SEND_MSGS);
  285. size = sizeof (paramp -> num_send_msgs);
  286. status = RegQueryValueEx (key, reg_path, 0L, & type,
  287. (LPBYTE) & paramp -> num_send_msgs, & size);
  288. if (status != ERROR_SUCCESS)
  289. paramp -> num_send_msgs = CVY_DEF_NUM_SEND_MSGS;
  290. swprintf (reg_path, L"%ls", CVY_NAME_DSCR_PER_ALLOC);
  291. size = sizeof (paramp -> dscr_per_alloc);
  292. status = RegQueryValueEx (key, reg_path, 0L, & type,
  293. (LPBYTE) & paramp -> dscr_per_alloc, & size);
  294. if (status != ERROR_SUCCESS)
  295. paramp -> dscr_per_alloc = CVY_DEF_DSCR_PER_ALLOC;
  296. swprintf (reg_path, L"%ls", CVY_NAME_MAX_DSCR_ALLOCS);
  297. size = sizeof (paramp -> max_dscr_allocs);
  298. status = RegQueryValueEx (key, reg_path, 0L, & type,
  299. (LPBYTE) & paramp -> max_dscr_allocs, & size);
  300. if (status != ERROR_SUCCESS)
  301. paramp -> max_dscr_allocs = CVY_DEF_MAX_DSCR_ALLOCS;
  302. swprintf (reg_path, L"%ls", CVY_NAME_SCALE_CLIENT);
  303. size = sizeof (paramp -> i_scale_client);
  304. status = RegQueryValueEx (key, reg_path, 0L, & type,
  305. (LPBYTE) & paramp -> i_scale_client, & size);
  306. if (status != ERROR_SUCCESS)
  307. paramp -> i_scale_client = CVY_DEF_SCALE_CLIENT;
  308. swprintf (reg_path, L"%ls", CVY_NAME_CLEANUP_DELAY);
  309. size = sizeof (paramp -> i_cleanup_delay);
  310. status = RegQueryValueEx (key, reg_path, 0L, & type,
  311. (LPBYTE) & paramp -> i_cleanup_delay, & size);
  312. if (status != ERROR_SUCCESS)
  313. paramp -> i_cleanup_delay = CVY_DEF_CLEANUP_DELAY;
  314. /* V1.1.1 */
  315. swprintf (reg_path, L"%ls", CVY_NAME_NBT_SUPPORT);
  316. size = sizeof (paramp -> i_nbt_support);
  317. status = RegQueryValueEx (key, reg_path, 0L, & type,
  318. (LPBYTE) & paramp -> i_nbt_support, & size);
  319. if (status != ERROR_SUCCESS)
  320. paramp -> i_nbt_support = CVY_DEF_NBT_SUPPORT;
  321. /* V1.3b */
  322. swprintf (reg_path, L"%ls", CVY_NAME_MCAST_SUPPORT);
  323. size = sizeof (paramp -> mcast_support);
  324. status = RegQueryValueEx (key, reg_path, 0L, & type,
  325. (LPBYTE) & paramp -> mcast_support, & size);
  326. if (status != ERROR_SUCCESS)
  327. paramp -> mcast_support = CVY_DEF_MCAST_SUPPORT;
  328. swprintf (reg_path, L"%ls", CVY_NAME_MCAST_SPOOF);
  329. size = sizeof (paramp -> i_mcast_spoof);
  330. status = RegQueryValueEx (key, reg_path, 0L, & type,
  331. (LPBYTE) & paramp -> i_mcast_spoof, & size);
  332. if (status != ERROR_SUCCESS)
  333. paramp -> i_mcast_spoof = CVY_DEF_MCAST_SPOOF;
  334. swprintf (reg_path, L"%ls", CVY_NAME_MASK_SRC_MAC);
  335. size = sizeof (paramp -> mask_src_mac);
  336. status = RegQueryValueEx (key, reg_path, 0L, & type,
  337. (LPBYTE) & paramp -> mask_src_mac, & size);
  338. if (status != ERROR_SUCCESS)
  339. paramp -> mask_src_mac = CVY_DEF_MASK_SRC_MAC;
  340. swprintf (reg_path, L"%ls", CVY_NAME_NETMON_ALIVE);
  341. size = sizeof (paramp -> i_netmon_alive);
  342. status = RegQueryValueEx (key, reg_path, 0L, & type,
  343. (LPBYTE) & paramp -> i_netmon_alive, & size);
  344. if (status != ERROR_SUCCESS)
  345. paramp -> i_netmon_alive = CVY_DEF_NETMON_ALIVE;
  346. swprintf (reg_path, L"%ls", CVY_NAME_EFFECTIVE_VERSION);
  347. size = sizeof (paramp -> i_effective_version);
  348. status = RegQueryValueEx (key, reg_path, 0L, & type,
  349. (LPBYTE) & paramp -> i_effective_version, & size);
  350. if (status != ERROR_SUCCESS)
  351. paramp -> i_effective_version = CVY_NT40_VERSION_FULL;
  352. swprintf (reg_path, L"%ls", CVY_NAME_IP_CHG_DELAY);
  353. size = sizeof (paramp -> i_ip_chg_delay);
  354. status = RegQueryValueEx (key, reg_path, 0L, & type,
  355. (LPBYTE) & paramp -> i_ip_chg_delay, & size);
  356. if (status != ERROR_SUCCESS)
  357. paramp -> i_ip_chg_delay = CVY_DEF_IP_CHG_DELAY;
  358. swprintf (reg_path, L"%ls", CVY_NAME_CONVERT_MAC);
  359. size = sizeof (paramp -> i_convert_mac);
  360. status = RegQueryValueEx (key, reg_path, 0L, & type,
  361. (LPBYTE) & paramp -> i_convert_mac, & size);
  362. if (status != ERROR_SUCCESS)
  363. paramp -> i_convert_mac = CVY_DEF_CONVERT_MAC;
  364. swprintf (reg_path, L"%ls", CVY_NAME_NUM_RULES);
  365. size = sizeof (paramp -> i_num_rules);
  366. status = RegQueryValueEx (key, reg_path, 0L, & type,
  367. (LPBYTE) & paramp -> i_num_rules, & size);
  368. if (status != ERROR_SUCCESS)
  369. paramp -> i_num_rules = 0;
  370. WLBS_OLD_PORT_RULE old_port_rules [WLBS_MAX_RULES];
  371. HKEY subkey;
  372. //
  373. // Attempt to read port rules from new location/format. If it is an upgrade from Win2k,
  374. // it will not be present in the new location.
  375. //
  376. if (!fUpgradeFromWin2k
  377. && (RegOpenKeyEx (key, CVY_NAME_PORT_RULES, 0L, KEY_QUERY_VALUE, & subkey) == ERROR_SUCCESS))
  378. {
  379. DWORD idx = 1, num_rules = paramp -> i_num_rules, correct_rules = 0;
  380. WLBS_PORT_RULE *port_rule;
  381. if (pfPortRulesInBinaryForm)
  382. *pfPortRulesInBinaryForm = false;
  383. port_rule = paramp -> i_port_rules;
  384. while(idx <= num_rules)
  385. {
  386. HKEY rule_key;
  387. wchar_t idx_str[8];
  388. // Open the per port-rule key "1", "2", "3", ...etc
  389. if (RegOpenKeyEx (subkey, _itow(idx, idx_str, 10), 0L, KEY_QUERY_VALUE, & rule_key) != ERROR_SUCCESS)
  390. {
  391. idx++;
  392. continue;
  393. }
  394. swprintf (reg_path, L"%ls", CVY_NAME_VIP);
  395. size = sizeof (port_rule -> virtual_ip_addr);
  396. status = RegQueryValueEx (rule_key, reg_path, 0L, & type, (LPBYTE) &port_rule->virtual_ip_addr, & size);
  397. if (status != ERROR_SUCCESS)
  398. {
  399. idx++;
  400. continue;
  401. }
  402. swprintf (reg_path, L"%ls", CVY_NAME_START_PORT);
  403. size = sizeof (port_rule ->start_port );
  404. status = RegQueryValueEx (rule_key, reg_path, 0L, & type, (LPBYTE) &port_rule->start_port, & size);
  405. if (status != ERROR_SUCCESS)
  406. {
  407. idx++;
  408. continue;
  409. }
  410. swprintf (reg_path, L"%ls", CVY_NAME_END_PORT);
  411. size = sizeof (port_rule ->end_port );
  412. status = RegQueryValueEx (rule_key, reg_path, 0L, & type, (LPBYTE) &port_rule->end_port, & size);
  413. if (status != ERROR_SUCCESS)
  414. {
  415. idx++;
  416. continue;
  417. }
  418. swprintf (reg_path, L"%ls", CVY_NAME_CODE);
  419. size = sizeof (port_rule ->code);
  420. status = RegQueryValueEx (rule_key, reg_path, 0L, & type, (LPBYTE) &port_rule->code, & size);
  421. if (status != ERROR_SUCCESS)
  422. {
  423. idx++;
  424. continue;
  425. }
  426. swprintf (reg_path, L"%ls", CVY_NAME_MODE);
  427. size = sizeof (port_rule->mode);
  428. status = RegQueryValueEx (rule_key, reg_path, 0L, & type, (LPBYTE) &port_rule->mode, & size);
  429. if (status != ERROR_SUCCESS)
  430. {
  431. idx++;
  432. continue;
  433. }
  434. swprintf (reg_path, L"%ls", CVY_NAME_PROTOCOL);
  435. size = sizeof (port_rule->protocol);
  436. status = RegQueryValueEx (rule_key, reg_path, 0L, & type, (LPBYTE) &port_rule->protocol, & size);
  437. if (status != ERROR_SUCCESS)
  438. {
  439. idx++;
  440. continue;
  441. }
  442. port_rule->valid = true;
  443. DWORD EqualLoad, Affinity;
  444. switch (port_rule->mode)
  445. {
  446. case CVY_MULTI :
  447. swprintf (reg_path, L"%ls", CVY_NAME_EQUAL_LOAD );
  448. size = sizeof (EqualLoad);
  449. status = RegQueryValueEx (rule_key, reg_path, 0L, & type, (LPBYTE) &EqualLoad, & size);
  450. if (status != ERROR_SUCCESS)
  451. {
  452. idx++;
  453. continue;
  454. }
  455. else
  456. {
  457. port_rule->mode_data.multi.equal_load = (WORD) EqualLoad;
  458. }
  459. swprintf (reg_path, L"%ls", CVY_NAME_AFFINITY );
  460. size = sizeof (Affinity);
  461. status = RegQueryValueEx (rule_key, reg_path, 0L, & type, (LPBYTE) &Affinity, & size);
  462. if (status != ERROR_SUCCESS)
  463. {
  464. idx++;
  465. continue;
  466. }
  467. else
  468. {
  469. port_rule->mode_data.multi.affinity = (WORD) Affinity;
  470. }
  471. swprintf (reg_path, L"%ls", CVY_NAME_LOAD);
  472. size = sizeof (port_rule->mode_data.multi.load);
  473. status = RegQueryValueEx (rule_key, reg_path, 0L, & type, (LPBYTE) &(port_rule->mode_data.multi.load), & size);
  474. if (status != ERROR_SUCCESS)
  475. {
  476. idx++;
  477. continue;
  478. }
  479. break;
  480. case CVY_SINGLE :
  481. swprintf (reg_path, L"%ls", CVY_NAME_PRIORITY);
  482. size = sizeof (port_rule->mode_data.single.priority);
  483. status = RegQueryValueEx (rule_key, reg_path, 0L, & type, (LPBYTE) &(port_rule->mode_data.single.priority), & size);
  484. if (status != ERROR_SUCCESS)
  485. {
  486. idx++;
  487. continue;
  488. }
  489. break;
  490. default:
  491. break;
  492. }
  493. port_rule++;
  494. idx++;
  495. correct_rules++;
  496. }
  497. // Discard those rules on which we encountered some error
  498. if (paramp->i_num_rules != correct_rules)
  499. {
  500. paramp -> i_num_rules = correct_rules;
  501. }
  502. }
  503. else // Port Rules in Binary Format
  504. {
  505. if (pfPortRulesInBinaryForm)
  506. *pfPortRulesInBinaryForm = true;
  507. swprintf (reg_path, L"%ls", CVY_NAME_OLD_PORT_RULES);
  508. size = sizeof (old_port_rules);
  509. status = RegQueryValueEx (key, reg_path, 0L, & type,
  510. (LPBYTE) old_port_rules, & size);
  511. if (status != ERROR_SUCCESS ||
  512. size % sizeof (WLBS_OLD_PORT_RULE) != 0 ||
  513. paramp -> i_num_rules != size / sizeof (WLBS_OLD_PORT_RULE))
  514. {
  515. ZeroMemory(paramp -> i_port_rules, sizeof(paramp -> i_port_rules));
  516. paramp -> i_num_rules = 0;
  517. }
  518. else // Convert the port rules to new format
  519. {
  520. if (paramp -> i_parms_ver > 3)
  521. {
  522. TransformOldPortRulesToNew(old_port_rules, paramp -> i_port_rules, paramp -> i_num_rules);
  523. }
  524. }
  525. }
  526. swprintf (reg_path, L"%ls", CVY_NAME_LICENSE_KEY);
  527. size = sizeof (paramp -> i_license_key);
  528. status = RegQueryValueEx (key, reg_path, 0L, & type,
  529. (LPBYTE) paramp -> i_license_key, & size);
  530. if (status != ERROR_SUCCESS)
  531. swprintf (paramp -> i_license_key, L"%ls", CVY_DEF_LICENSE_KEY);
  532. swprintf (reg_path, L"%ls", CVY_NAME_RMT_PASSWORD);
  533. size = sizeof (paramp -> i_rmt_password);
  534. status = RegQueryValueEx (key, reg_path, 0L, & type,
  535. (LPBYTE) & paramp -> i_rmt_password, & size);
  536. if (status != ERROR_SUCCESS)
  537. paramp -> i_rmt_password = CVY_DEF_RMT_PASSWORD;
  538. swprintf (reg_path, L"%ls", CVY_NAME_RCT_PASSWORD);
  539. size = sizeof (paramp -> i_rct_password);
  540. status = RegQueryValueEx (key, reg_path, 0L, & type,
  541. (LPBYTE) & paramp -> i_rct_password, & size);
  542. if (status != ERROR_SUCCESS)
  543. paramp -> i_rct_password = CVY_DEF_RCT_PASSWORD;
  544. swprintf (reg_path, L"%ls", CVY_NAME_RCT_PORT);
  545. size = sizeof (paramp -> rct_port);
  546. status = RegQueryValueEx (key, reg_path, 0L, & type,
  547. (LPBYTE) & paramp -> rct_port, & size);
  548. if (status != ERROR_SUCCESS)
  549. paramp -> rct_port = CVY_DEF_RCT_PORT;
  550. swprintf (reg_path, L"%ls", CVY_NAME_RCT_ENABLED);
  551. size = sizeof (paramp -> rct_enabled);
  552. status = RegQueryValueEx (key, reg_path, 0L, & type,
  553. (LPBYTE) & paramp -> rct_enabled, & size);
  554. if (status != ERROR_SUCCESS)
  555. paramp -> rct_enabled = CVY_DEF_RCT_ENABLED;
  556. //
  557. // IGMP support registry entries
  558. //
  559. size = sizeof (paramp->fIGMPSupport);
  560. status = RegQueryValueEx (key, CVY_NAME_IGMP_SUPPORT, 0L, NULL,
  561. (LPBYTE) & paramp->fIGMPSupport, &size);
  562. if (status != ERROR_SUCCESS)
  563. paramp -> fIGMPSupport = CVY_DEF_IGMP_SUPPORT;
  564. size = sizeof (paramp->szMCastIpAddress);
  565. status = RegQueryValueEx (key, CVY_NAME_MCAST_IP_ADDR, 0L, NULL,
  566. (LPBYTE) & paramp->szMCastIpAddress, &size);
  567. if (status != ERROR_SUCCESS)
  568. lstrcpy(paramp -> szMCastIpAddress, CVY_DEF_MCAST_IP_ADDR);
  569. size = sizeof (paramp->fIpToMCastIp);
  570. status = RegQueryValueEx (key, CVY_NAME_IP_TO_MCASTIP, 0L, NULL,
  571. (LPBYTE) & paramp->fIpToMCastIp, &size);
  572. if (status != ERROR_SUCCESS)
  573. paramp -> fIpToMCastIp = CVY_DEF_IP_TO_MCASTIP;
  574. /* Attempt to open the BDA teaming settings. They may not be there,
  575. so if they aren't, move on; otherwise, extract the settings. */
  576. if ((bda_key = RegOpenWlbsBDASettings(AdapterGuid, true))) {
  577. GUID TeamGuid;
  578. HRESULT hr;
  579. /* If the key exists, we are part of a team. */
  580. paramp->bda_teaming.active = TRUE;
  581. /* Find out if we are the master of this team. */
  582. size = sizeof (paramp->bda_teaming.master);
  583. status = RegQueryValueEx (bda_key, CVY_NAME_BDA_MASTER, 0L, NULL,
  584. (LPBYTE)&paramp->bda_teaming.master, &size);
  585. /* If we can't get that information, default to a slave. */
  586. if (status != ERROR_SUCCESS)
  587. paramp->bda_teaming.master = FALSE;
  588. /* Find out if we are reverse hashing or not. */
  589. size = sizeof (paramp->bda_teaming.reverse_hash);
  590. status = RegQueryValueEx (bda_key, CVY_NAME_BDA_REVERSE_HASH, 0L, NULL,
  591. (LPBYTE)&paramp->bda_teaming.reverse_hash, &size);
  592. /* If that fails, then assume normal hashing. */
  593. if (status != ERROR_SUCCESS)
  594. paramp->bda_teaming.reverse_hash = FALSE;
  595. /* Get our team ID - this should be a GUID, be we don't enforce that. */
  596. size = sizeof (paramp->bda_teaming.team_id);
  597. status = RegQueryValueEx (bda_key, CVY_NAME_BDA_TEAM_ID, 0L, NULL,
  598. (LPBYTE)&paramp->bda_teaming.team_id, &size);
  599. /* The team is absolutely required - if we can't get it, then don't join the team. */
  600. if (status != ERROR_SUCCESS)
  601. paramp->bda_teaming.active = CVY_DEF_BDA_ACTIVE;
  602. /* Attempt to convert the string to a GUID and check for errors. */
  603. hr = CLSIDFromString(paramp->bda_teaming.team_id, &TeamGuid);
  604. /* If the conversion fails, bail out - the team ID must not have been a GUID. */
  605. if (hr != NOERROR) {
  606. LOG_ERROR1("ParamReadReg: Invalid BDA Team ID: %ls", paramp->bda_teaming.team_id);
  607. paramp->bda_teaming.active = CVY_DEF_BDA_ACTIVE;
  608. }
  609. RegCloseKey(bda_key);
  610. }
  611. /* decode port rules prior to version 3 */
  612. if (paramp -> i_parms_ver <= 3)
  613. {
  614. paramp -> i_parms_ver = CVY_PARAMS_VERSION;
  615. /* decode the port rules */
  616. if (! License_data_decode ((PCHAR) old_port_rules, paramp -> i_num_rules * sizeof (WLBS_OLD_PORT_RULE)))
  617. {
  618. ZeroMemory(paramp -> i_port_rules, sizeof(paramp -> i_port_rules));
  619. paramp -> i_num_rules = 0;
  620. }
  621. else
  622. TransformOldPortRulesToNew(old_port_rules, paramp -> i_port_rules, paramp -> i_num_rules);
  623. }
  624. /* upgrade port rules from params V1 to params V2 */
  625. if (paramp -> i_parms_ver == 1)
  626. {
  627. paramp -> i_parms_ver = CVY_PARAMS_VERSION;
  628. /* keep multicast off by default for old users */
  629. paramp -> mcast_support = FALSE;
  630. for (i = 0; i < paramp -> i_num_rules; i ++)
  631. {
  632. rp = paramp -> i_port_rules + i;
  633. code = CVY_RULE_CODE_GET (rp);
  634. CVY_RULE_CODE_SET (rp);
  635. if (code != CVY_RULE_CODE_GET (rp))
  636. {
  637. rp -> code = code;
  638. continue;
  639. }
  640. if (! rp -> valid)
  641. {
  642. continue;
  643. }
  644. /* set affinity according to current ScaleSingleClient setting */
  645. if (rp -> mode == CVY_MULTI)
  646. rp -> mode_data . multi . affinity = CVY_AFFINITY_SINGLE - (USHORT)paramp -> i_scale_client;
  647. CVY_RULE_CODE_SET (rp);
  648. }
  649. }
  650. /* upgrade max number of descriptor allocs */
  651. if (paramp -> i_parms_ver == 2)
  652. {
  653. paramp -> i_parms_ver = CVY_PARAMS_VERSION;
  654. paramp -> max_dscr_allocs = CVY_DEF_MAX_DSCR_ALLOCS;
  655. paramp -> dscr_per_alloc = CVY_DEF_DSCR_PER_ALLOC;
  656. }
  657. RegCloseKey (key);
  658. paramp -> i_max_hosts = CVY_MAX_HOSTS;
  659. paramp -> i_max_rules = CVY_MAX_USABLE_RULES;
  660. // paramp -> i_ft_rules_enabled = TRUE;
  661. // paramp -> version = 0;
  662. // CLEAN_64BIT CVY_CHECK_MIN (paramp -> i_num_rules, CVY_MIN_NUM_RULES);
  663. CVY_CHECK_MAX (paramp -> i_num_rules, CVY_MAX_NUM_RULES);
  664. CVY_CHECK_MIN (paramp -> host_priority, CVY_MIN_HOST_PRIORITY);
  665. CVY_CHECK_MAX (paramp -> host_priority, CVY_MAX_HOST_PRIORITY);
  666. return TRUE;
  667. }
  668. //+----------------------------------------------------------------------------
  669. //
  670. // Function: ParamValidate
  671. //
  672. // Description: Validates the cluster parameters. Also munges some fields
  673. // such as IP addresses to make them canonocal.
  674. //
  675. // Arguments: PWLBS_REG_PARAMS paramp -
  676. //
  677. // Returns: bool - TRUE if params are valid, false otherwise
  678. //
  679. // History: josephj Created 4/25/01 based on code from ParamWriteReg.
  680. //
  681. //+----------------------------------------------------------------------------
  682. bool WINAPI ParamValidate(const PWLBS_REG_PARAMS paramp)
  683. {
  684. bool fRet = FALSE;
  685. DWORD idx;
  686. IN_ADDR dwIPAddr;
  687. CHAR * szIPAddr;
  688. DWORD num_rules;
  689. WLBS_PORT_RULE *port_rule;
  690. /* verify and if necessary reset the parameters */
  691. CVY_CHECK_MIN (paramp -> alive_period, CVY_MIN_ALIVE_PERIOD);
  692. CVY_CHECK_MAX (paramp -> alive_period, CVY_MAX_ALIVE_PERIOD);
  693. CVY_CHECK_MIN (paramp -> alive_tolerance, CVY_MIN_ALIVE_TOLER);
  694. CVY_CHECK_MAX (paramp -> alive_tolerance, CVY_MAX_ALIVE_TOLER);
  695. CVY_CHECK_MIN (paramp -> num_actions, CVY_MIN_NUM_ACTIONS);
  696. CVY_CHECK_MAX (paramp -> num_actions, CVY_MAX_NUM_ACTIONS);
  697. CVY_CHECK_MIN (paramp -> num_packets, CVY_MIN_NUM_PACKETS);
  698. CVY_CHECK_MAX (paramp -> num_packets, CVY_MAX_NUM_PACKETS);
  699. CVY_CHECK_MIN (paramp -> dscr_per_alloc, CVY_MIN_DSCR_PER_ALLOC);
  700. CVY_CHECK_MAX (paramp -> dscr_per_alloc, CVY_MAX_DSCR_PER_ALLOC);
  701. CVY_CHECK_MIN (paramp -> max_dscr_allocs, CVY_MIN_MAX_DSCR_ALLOCS);
  702. CVY_CHECK_MAX (paramp -> max_dscr_allocs, CVY_MAX_MAX_DSCR_ALLOCS);
  703. // CLEAN_64BIT CVY_CHECK_MIN (paramp -> i_cleanup_delay, CVY_MIN_CLEANUP_DELAY);
  704. CVY_CHECK_MAX (paramp -> i_cleanup_delay, CVY_MAX_CLEANUP_DELAY);
  705. // CLEAN_64BIT CVY_CHECK_MIN (paramp -> i_ip_chg_delay, CVY_MIN_IP_CHG_DELAY);
  706. CVY_CHECK_MAX (paramp -> i_ip_chg_delay, CVY_MAX_IP_CHG_DELAY);
  707. CVY_CHECK_MIN (paramp -> num_send_msgs, (paramp -> i_max_hosts + 1) * 2);
  708. CVY_CHECK_MAX (paramp -> num_send_msgs, (paramp -> i_max_hosts + 1) * 10);
  709. // CLEAN_64BIT CVY_CHECK_MIN (paramp -> i_num_rules, CVY_MIN_NUM_RULES);
  710. CVY_CHECK_MAX (paramp -> i_num_rules, CVY_MAX_NUM_RULES);
  711. CVY_CHECK_MIN (paramp -> host_priority, CVY_MIN_HOST_PRIORITY);
  712. CVY_CHECK_MAX (paramp -> host_priority, CVY_MAX_HOST_PRIORITY);
  713. // CLEAN_64BIT CVY_CHECK_MIN (paramp -> cluster_mode, CVY_MIN_CLUSTER_MODE);
  714. CVY_CHECK_MAX (paramp -> cluster_mode, CVY_MAX_CLUSTER_MODE);
  715. /* If the cluster IP address is not 0.0.0.0, then make sure the IP address is valid. */
  716. if (lstrcmpi(paramp->cl_ip_addr, CVY_DEF_CL_IP_ADDR)) {
  717. /* Check the validity of the IP address. */
  718. if (!(dwIPAddr.S_un.S_addr = IpAddressFromAbcdWsz(paramp->cl_ip_addr)))
  719. goto error;
  720. /* Convert the DWORD back to a string. We do this because 11.11.3 is a valid IP
  721. address the inet_addr converts to 11.11.0.3 as a DWORD. Therefore, to keep
  722. the IP address string (which is used by other parts of NLB, such as the UI)
  723. consistent, we convert back to a string. */
  724. if (!(szIPAddr = inet_ntoa(dwIPAddr)))
  725. goto error;
  726. /* Convert the ASCII string to unicode. */
  727. if (!MultiByteToWideChar(CP_ACP, 0, szIPAddr, -1, paramp->cl_ip_addr, WLBS_MAX_CL_IP_ADDR + 1))
  728. goto error;
  729. }
  730. /* If the cluster netmask is not 0.0.0.0, then make sure the netmask is valid. */
  731. if (lstrcmpi(paramp->cl_net_mask, CVY_DEF_CL_NET_MASK)) {
  732. /* Check the validity of the IP address. */
  733. if (!(dwIPAddr.S_un.S_addr = IpAddressFromAbcdWsz(paramp->cl_net_mask)))
  734. goto error;
  735. /* Convert the DWORD back to a string. We do this because 11.11.3 is a valid IP
  736. address the inet_addr converts to 11.11.0.3 as a DWORD. Therefore, to keep
  737. the IP address string (which is used by other parts of NLB, such as the UI)
  738. consistent, we convert back to a string. */
  739. if (!(szIPAddr = inet_ntoa(dwIPAddr)))
  740. goto error;
  741. /* Convert the ASCII string to unicode. */
  742. if (!MultiByteToWideChar(CP_ACP, 0, szIPAddr, -1, paramp->cl_net_mask, WLBS_MAX_CL_NET_MASK + 1))
  743. goto error;
  744. }
  745. /* If the dedicated IP address is not 0.0.0.0, then make sure the IP address is valid. */
  746. if (lstrcmpi(paramp->ded_ip_addr, CVY_DEF_DED_IP_ADDR)) {
  747. /* Check the validity of the IP address. */
  748. if (!(dwIPAddr.S_un.S_addr = IpAddressFromAbcdWsz(paramp->ded_ip_addr)))
  749. goto error;
  750. /* Convert the DWORD back to a string. We do this because 11.11.3 is a valid IP
  751. address the inet_addr converts to 11.11.0.3 as a DWORD. Therefore, to keep
  752. the IP address string (which is used by other parts of NLB, such as the UI)
  753. consistent, we convert back to a string. */
  754. if (!(szIPAddr = inet_ntoa(dwIPAddr)))
  755. goto error;
  756. /* Convert the ASCII string to unicode. */
  757. if (!MultiByteToWideChar(CP_ACP, 0, szIPAddr, -1, paramp->ded_ip_addr, WLBS_MAX_DED_IP_ADDR + 1))
  758. goto error;
  759. }
  760. /* If the dedicated netmask is not 0.0.0.0, then make sure the netmask is valid. */
  761. if (lstrcmpi(paramp->ded_net_mask, CVY_DEF_DED_NET_MASK)) {
  762. /* Check the validity of the IP address. */
  763. if (!(dwIPAddr.S_un.S_addr = IpAddressFromAbcdWsz(paramp->ded_net_mask)))
  764. goto error;
  765. /* Convert the DWORD back to a string. We do this because 11.11.3 is a valid IP
  766. address the inet_addr converts to 11.11.0.3 as a DWORD. Therefore, to keep
  767. the IP address string (which is used by other parts of NLB, such as the UI)
  768. consistent, we convert back to a string. */
  769. if (!(szIPAddr = inet_ntoa(dwIPAddr)))
  770. goto error;
  771. /* Convert the ASCII string to unicode. */
  772. if (!MultiByteToWideChar(CP_ACP, 0, szIPAddr, -1, paramp->ded_net_mask, WLBS_MAX_DED_NET_MASK + 1))
  773. goto error;
  774. }
  775. /* Verify that the port rule VIP is valid,
  776. Also, convert the port rule VIPs that might be in the x.x.x or x.x or x form to x.x.x.x */
  777. idx = 0;
  778. num_rules = paramp -> i_num_rules;
  779. while (idx < num_rules)
  780. {
  781. port_rule = &paramp->i_port_rules[idx];
  782. /* Check if the port rule is valid and the vip is not "All Vip" */
  783. if (port_rule->valid && lstrcmpi(port_rule->virtual_ip_addr, CVY_DEF_ALL_VIP))
  784. {
  785. /* Get IP Address into DWORD form */
  786. if (!(dwIPAddr.S_un.S_addr = IpAddressFromAbcdWsz(port_rule->virtual_ip_addr)))
  787. goto error;
  788. /* Check for validity of IP Address */
  789. if ((dwIPAddr.S_un.S_un_b.s_b1 < WLBS_IP_FIELD_ZERO_LOW)
  790. || (dwIPAddr.S_un.S_un_b.s_b1 > WLBS_IP_FIELD_ZERO_HIGH)
  791. || (dwIPAddr.S_un.S_un_b.s_b2 < WLBS_FIELD_LOW)
  792. || (dwIPAddr.S_un.S_un_b.s_b2 > WLBS_FIELD_HIGH)
  793. || (dwIPAddr.S_un.S_un_b.s_b3 < WLBS_FIELD_LOW)
  794. || (dwIPAddr.S_un.S_un_b.s_b3 > WLBS_FIELD_HIGH)
  795. || (dwIPAddr.S_un.S_un_b.s_b4 < WLBS_FIELD_LOW)
  796. || (dwIPAddr.S_un.S_un_b.s_b4 > WLBS_FIELD_HIGH))
  797. goto error;
  798. /* Convert the DWORD back to a string. We do this because 11.11.3 is a valid IP
  799. address the inet_addr converts to 11.11.0.3 as a DWORD. Therefore, to keep
  800. the IP address string (which is used by other parts of NLB, such as the UI)
  801. consistent, we convert back to a string. */
  802. if (!(szIPAddr = inet_ntoa(dwIPAddr)))
  803. goto error;
  804. /* Convert the ASCII string to unicode. */
  805. if (!MultiByteToWideChar(CP_ACP, 0, szIPAddr, -1, port_rule->virtual_ip_addr, WLBS_MAX_CL_IP_ADDR + 1))
  806. goto error;
  807. }
  808. idx++;
  809. }
  810. /* If either the cluster IP address or the cluster netmask is not 0.0.0.0,
  811. then make sure the they are a valid IP address/netmask pair. */
  812. if (lstrcmpi(paramp->cl_ip_addr, CVY_DEF_CL_IP_ADDR) || lstrcmpi(paramp->cl_net_mask, CVY_DEF_CL_NET_MASK)) {
  813. /* If they have specified a cluster IP address, but no netmask, then fill it in for them. */
  814. if (!lstrcmpi(paramp->cl_net_mask, CVY_DEF_CL_NET_MASK))
  815. ParamsGenerateSubnetMask(paramp->cl_ip_addr, paramp->cl_net_mask);
  816. /* Check for valid cluster IP address/netmask pairs. */
  817. if (!IsValidIPAddressSubnetMaskPair(paramp->cl_ip_addr, paramp->cl_net_mask))
  818. goto error;
  819. /* Check to make sure that the cluster netmask is contiguous. */
  820. if (!IsContiguousSubnetMask(paramp->cl_net_mask))
  821. goto error;
  822. /* Check to make sure that the dedicated IP and cluster IP are not the same. */
  823. if (!wcscmp(paramp->ded_ip_addr, paramp->cl_ip_addr))
  824. goto error;
  825. }
  826. /* If either the dedicated IP address or the dedicated netmask is not 0.0.0.0,
  827. then make sure the they are a valid IP address/netmask pair. */
  828. if (lstrcmpi(paramp->ded_ip_addr, CVY_DEF_DED_IP_ADDR) || lstrcmpi(paramp->ded_net_mask, CVY_DEF_DED_NET_MASK)) {
  829. /* If they have specified a cluster IP address, but no netmask, then fill it in for them. */
  830. if (!lstrcmpi(paramp->ded_net_mask, CVY_DEF_DED_NET_MASK))
  831. ParamsGenerateSubnetMask(paramp->ded_ip_addr, paramp->ded_net_mask);
  832. /* Check for valid dedicated IP address/netmask pairs. */
  833. if (!IsValidIPAddressSubnetMaskPair(paramp->ded_ip_addr, paramp->ded_net_mask))
  834. goto error;
  835. /* Check to make sure that the dedicated netmask is contiguous. */
  836. if (!IsContiguousSubnetMask(paramp->ded_net_mask))
  837. goto error;
  838. }
  839. /* Check the mac address if the convert_mac flag is not set */
  840. if ( ! paramp -> i_convert_mac)
  841. {
  842. PWCHAR p1, p2;
  843. WCHAR mac_addr [WLBS_MAX_NETWORK_ADDR + 1];
  844. DWORD i, j;
  845. BOOL flag = TRUE;
  846. _tcscpy (mac_addr, paramp -> cl_mac_addr);
  847. p2 = p1 = mac_addr;
  848. for (i = 0 ; i < 6 ; i++)
  849. {
  850. if (*p2 == _TEXT('\0'))
  851. {
  852. flag = FALSE;
  853. break;
  854. }
  855. j = _tcstoul (p1, &p2, 16);
  856. if ( j > 255)
  857. {
  858. flag = FALSE;
  859. break;
  860. }
  861. if ( ! (*p2 == _TEXT('-') || *p2 == _TEXT(':') || *p2 == _TEXT('\0')) )
  862. {
  863. flag = FALSE;
  864. break;
  865. }
  866. if (*p2 == _TEXT('\0') && i < 5)
  867. {
  868. flag = FALSE;
  869. break;
  870. }
  871. p1 = p2 + 1;
  872. p2 = p1;
  873. }
  874. if (!flag)
  875. {
  876. goto error;
  877. }
  878. }
  879. if (paramp->fIGMPSupport && !paramp->mcast_support)
  880. {
  881. //
  882. // IGMP can not be enabled in unicast mode
  883. //
  884. LOG_ERROR("ParamWriteReg IGMP can not be enabled in unicast mode");
  885. goto error;
  886. }
  887. if (paramp->mcast_support && paramp->fIGMPSupport && !paramp->fIpToMCastIp)
  888. {
  889. //
  890. // Multicast mode with IGMP enabled, and user specified an multicast IP address,
  891. // The multicast IP address should be in the range of (224-239).x.x.x
  892. // but NOT (224-239).0.0.x or (224-239).128.0.x.
  893. //
  894. DWORD dwMCastIp = IpAddressFromAbcdWsz(paramp->szMCastIpAddress);
  895. if ((dwMCastIp & 0xf0) != 0xe0 ||
  896. (dwMCastIp & 0x00ffff00) == 0 ||
  897. (dwMCastIp & 0x00ffff00) == 0x00008000)
  898. {
  899. LOG_ERROR1("ParamWriteReg invalid szMCastIpAddressr %ws",
  900. paramp->szMCastIpAddress);
  901. goto error;
  902. }
  903. }
  904. /* Generate the MAC address. */
  905. ParamsGenerateMAC(paramp->cl_ip_addr, paramp->cl_mac_addr, paramp->szMCastIpAddress, paramp->i_convert_mac,
  906. paramp->mcast_support, paramp->fIGMPSupport, paramp->fIpToMCastIp);
  907. fRet = TRUE;
  908. goto end;
  909. error:
  910. fRet = FALSE;
  911. goto end;
  912. end:
  913. return fRet;
  914. }
  915. //+----------------------------------------------------------------------------
  916. //
  917. // Function: ParamWriteReg
  918. //
  919. // Description: Write cluster settings to registry
  920. //
  921. // Arguments: const GUID& AdapterGuid -
  922. // PWLBS_REG_PARAMS paramp -
  923. //
  924. // Returns: bool -
  925. //
  926. // History: fengsun Created Header 3/9/00
  927. //
  928. //+----------------------------------------------------------------------------
  929. bool WINAPI ParamWriteReg(const GUID& AdapterGuid, PWLBS_REG_PARAMS paramp)
  930. {
  931. HKEY bda_key = NULL;
  932. HKEY key = NULL;
  933. DWORD size;
  934. LONG status;
  935. DWORD disp, idx;
  936. DWORD num_rules;
  937. WLBS_PORT_RULE *port_rule;
  938. #if 1
  939. if (!ParamValidate(paramp))
  940. goto error;
  941. num_rules = paramp -> i_num_rules;
  942. #else // OBSOLETE_CODE
  943. IN_ADDR dwIPAddr;
  944. CHAR * szIPAddr;
  945. /* verify and if necessary reset the parameters */
  946. CVY_CHECK_MIN (paramp -> alive_period, CVY_MIN_ALIVE_PERIOD);
  947. CVY_CHECK_MAX (paramp -> alive_period, CVY_MAX_ALIVE_PERIOD);
  948. CVY_CHECK_MIN (paramp -> alive_tolerance, CVY_MIN_ALIVE_TOLER);
  949. CVY_CHECK_MAX (paramp -> alive_tolerance, CVY_MAX_ALIVE_TOLER);
  950. CVY_CHECK_MIN (paramp -> num_actions, CVY_MIN_NUM_ACTIONS);
  951. CVY_CHECK_MAX (paramp -> num_actions, CVY_MAX_NUM_ACTIONS);
  952. CVY_CHECK_MIN (paramp -> num_packets, CVY_MIN_NUM_PACKETS);
  953. CVY_CHECK_MAX (paramp -> num_packets, CVY_MAX_NUM_PACKETS);
  954. CVY_CHECK_MIN (paramp -> dscr_per_alloc, CVY_MIN_DSCR_PER_ALLOC);
  955. CVY_CHECK_MAX (paramp -> dscr_per_alloc, CVY_MAX_DSCR_PER_ALLOC);
  956. CVY_CHECK_MIN (paramp -> max_dscr_allocs, CVY_MIN_MAX_DSCR_ALLOCS);
  957. CVY_CHECK_MAX (paramp -> max_dscr_allocs, CVY_MAX_MAX_DSCR_ALLOCS);
  958. // CLEAN_64BIT CVY_CHECK_MIN (paramp -> i_cleanup_delay, CVY_MIN_CLEANUP_DELAY);
  959. CVY_CHECK_MAX (paramp -> i_cleanup_delay, CVY_MAX_CLEANUP_DELAY);
  960. // CLEAN_64BIT CVY_CHECK_MIN (paramp -> i_ip_chg_delay, CVY_MIN_IP_CHG_DELAY);
  961. CVY_CHECK_MAX (paramp -> i_ip_chg_delay, CVY_MAX_IP_CHG_DELAY);
  962. CVY_CHECK_MIN (paramp -> num_send_msgs, (paramp -> i_max_hosts + 1) * 2);
  963. CVY_CHECK_MAX (paramp -> num_send_msgs, (paramp -> i_max_hosts + 1) * 10);
  964. // CLEAN_64BIT CVY_CHECK_MIN (paramp -> i_num_rules, CVY_MIN_NUM_RULES);
  965. CVY_CHECK_MAX (paramp -> i_num_rules, CVY_MAX_NUM_RULES);
  966. CVY_CHECK_MIN (paramp -> host_priority, CVY_MIN_HOST_PRIORITY);
  967. CVY_CHECK_MAX (paramp -> host_priority, CVY_MAX_HOST_PRIORITY);
  968. // CLEAN_64BIT CVY_CHECK_MIN (paramp -> cluster_mode, CVY_MIN_CLUSTER_MODE);
  969. CVY_CHECK_MAX (paramp -> cluster_mode, CVY_MAX_CLUSTER_MODE);
  970. /* If the cluster IP address is not 0.0.0.0, then make sure the IP address is valid. */
  971. if (lstrcmpi(paramp->cl_ip_addr, CVY_DEF_CL_IP_ADDR)) {
  972. /* Check the validity of the IP address. */
  973. if (!(dwIPAddr.S_un.S_addr = IpAddressFromAbcdWsz(paramp->cl_ip_addr)))
  974. goto error;
  975. /* Convert the DWORD back to a string. We do this because 11.11.3 is a valid IP
  976. address the inet_addr converts to 11.11.0.3 as a DWORD. Therefore, to keep
  977. the IP address string (which is used by other parts of NLB, such as the UI)
  978. consistent, we convert back to a string. */
  979. if (!(szIPAddr = inet_ntoa(dwIPAddr)))
  980. goto error;
  981. /* Convert the ASCII string to unicode. */
  982. if (!MultiByteToWideChar(CP_ACP, 0, szIPAddr, -1, paramp->cl_ip_addr, WLBS_MAX_CL_IP_ADDR + 1))
  983. goto error;
  984. }
  985. /* If the cluster netmask is not 0.0.0.0, then make sure the netmask is valid. */
  986. if (lstrcmpi(paramp->cl_net_mask, CVY_DEF_CL_NET_MASK)) {
  987. /* Check the validity of the IP address. */
  988. if (!(dwIPAddr.S_un.S_addr = IpAddressFromAbcdWsz(paramp->cl_net_mask)))
  989. goto error;
  990. /* Convert the DWORD back to a string. We do this because 11.11.3 is a valid IP
  991. address the inet_addr converts to 11.11.0.3 as a DWORD. Therefore, to keep
  992. the IP address string (which is used by other parts of NLB, such as the UI)
  993. consistent, we convert back to a string. */
  994. if (!(szIPAddr = inet_ntoa(dwIPAddr)))
  995. goto error;
  996. /* Convert the ASCII string to unicode. */
  997. if (!MultiByteToWideChar(CP_ACP, 0, szIPAddr, -1, paramp->cl_net_mask, WLBS_MAX_CL_NET_MASK + 1))
  998. goto error;
  999. }
  1000. /* If the dedicated IP address is not 0.0.0.0, then make sure the IP address is valid. */
  1001. if (lstrcmpi(paramp->ded_ip_addr, CVY_DEF_DED_IP_ADDR)) {
  1002. /* Check the validity of the IP address. */
  1003. if (!(dwIPAddr.S_un.S_addr = IpAddressFromAbcdWsz(paramp->ded_ip_addr)))
  1004. goto error;
  1005. /* Convert the DWORD back to a string. We do this because 11.11.3 is a valid IP
  1006. address the inet_addr converts to 11.11.0.3 as a DWORD. Therefore, to keep
  1007. the IP address string (which is used by other parts of NLB, such as the UI)
  1008. consistent, we convert back to a string. */
  1009. if (!(szIPAddr = inet_ntoa(dwIPAddr)))
  1010. goto error;
  1011. /* Convert the ASCII string to unicode. */
  1012. if (!MultiByteToWideChar(CP_ACP, 0, szIPAddr, -1, paramp->ded_ip_addr, WLBS_MAX_DED_IP_ADDR + 1))
  1013. goto error;
  1014. }
  1015. /* If the dedicated netmask is not 0.0.0.0, then make sure the netmask is valid. */
  1016. if (lstrcmpi(paramp->ded_net_mask, CVY_DEF_DED_NET_MASK)) {
  1017. /* Check the validity of the IP address. */
  1018. if (!(dwIPAddr.S_un.S_addr = IpAddressFromAbcdWsz(paramp->ded_net_mask)))
  1019. goto error;
  1020. /* Convert the DWORD back to a string. We do this because 11.11.3 is a valid IP
  1021. address the inet_addr converts to 11.11.0.3 as a DWORD. Therefore, to keep
  1022. the IP address string (which is used by other parts of NLB, such as the UI)
  1023. consistent, we convert back to a string. */
  1024. if (!(szIPAddr = inet_ntoa(dwIPAddr)))
  1025. goto error;
  1026. /* Convert the ASCII string to unicode. */
  1027. if (!MultiByteToWideChar(CP_ACP, 0, szIPAddr, -1, paramp->ded_net_mask, WLBS_MAX_DED_NET_MASK + 1))
  1028. goto error;
  1029. }
  1030. /* Verify that the port rule VIP is valid,
  1031. Also, convert the port rule VIPs that might be in the x.x.x or x.x or x form to x.x.x.x */
  1032. idx = 0;
  1033. num_rules = paramp -> i_num_rules;
  1034. while (idx < num_rules)
  1035. {
  1036. port_rule = &paramp->i_port_rules[idx];
  1037. /* Check if the port rule is valid and the vip is not "All Vip" */
  1038. if (port_rule->valid && lstrcmpi(port_rule->virtual_ip_addr, CVY_DEF_ALL_VIP))
  1039. {
  1040. /* Get IP Address into DWORD form */
  1041. if (!(dwIPAddr.S_un.S_addr = IpAddressFromAbcdWsz(port_rule->virtual_ip_addr)))
  1042. goto error;
  1043. /* Check for validity of IP Address */
  1044. if ((dwIPAddr.S_un.S_un_b.s_b1 < WLBS_IP_FIELD_ZERO_LOW)
  1045. || (dwIPAddr.S_un.S_un_b.s_b1 > WLBS_IP_FIELD_ZERO_HIGH)
  1046. || (dwIPAddr.S_un.S_un_b.s_b2 < WLBS_FIELD_LOW)
  1047. || (dwIPAddr.S_un.S_un_b.s_b2 > WLBS_FIELD_HIGH)
  1048. || (dwIPAddr.S_un.S_un_b.s_b3 < WLBS_FIELD_LOW)
  1049. || (dwIPAddr.S_un.S_un_b.s_b3 > WLBS_FIELD_HIGH)
  1050. || (dwIPAddr.S_un.S_un_b.s_b4 < WLBS_FIELD_LOW)
  1051. || (dwIPAddr.S_un.S_un_b.s_b4 > WLBS_FIELD_HIGH))
  1052. goto error;
  1053. /* Convert the DWORD back to a string. We do this because 11.11.3 is a valid IP
  1054. address the inet_addr converts to 11.11.0.3 as a DWORD. Therefore, to keep
  1055. the IP address string (which is used by other parts of NLB, such as the UI)
  1056. consistent, we convert back to a string. */
  1057. if (!(szIPAddr = inet_ntoa(dwIPAddr)))
  1058. goto error;
  1059. /* Convert the ASCII string to unicode. */
  1060. if (!MultiByteToWideChar(CP_ACP, 0, szIPAddr, -1, port_rule->virtual_ip_addr, WLBS_MAX_CL_IP_ADDR + 1))
  1061. goto error;
  1062. }
  1063. idx++;
  1064. }
  1065. /* If either the cluster IP address or the cluster netmask is not 0.0.0.0,
  1066. then make sure the they are a valid IP address/netmask pair. */
  1067. if (lstrcmpi(paramp->cl_ip_addr, CVY_DEF_CL_IP_ADDR) || lstrcmpi(paramp->cl_net_mask, CVY_DEF_CL_NET_MASK)) {
  1068. /* If they have specified a cluster IP address, but no netmask, then fill it in for them. */
  1069. if (!lstrcmpi(paramp->cl_net_mask, CVY_DEF_CL_NET_MASK))
  1070. ParamsGenerateSubnetMask(paramp->cl_ip_addr, paramp->cl_net_mask);
  1071. /* Check for valid cluster IP address/netmask pairs. */
  1072. if (!IsValidIPAddressSubnetMaskPair(paramp->cl_ip_addr, paramp->cl_net_mask))
  1073. goto error;
  1074. /* Check to make sure that the cluster netmask is contiguous. */
  1075. if (!IsContiguousSubnetMask(paramp->cl_net_mask))
  1076. goto error;
  1077. /* Check to make sure that the dedicated IP and cluster IP are not the same. */
  1078. if (!wcscmp(paramp->ded_ip_addr, paramp->cl_ip_addr))
  1079. goto error;
  1080. }
  1081. /* If either the dedicated IP address or the dedicated netmask is not 0.0.0.0,
  1082. then make sure the they are a valid IP address/netmask pair. */
  1083. if (lstrcmpi(paramp->ded_ip_addr, CVY_DEF_DED_IP_ADDR) || lstrcmpi(paramp->ded_net_mask, CVY_DEF_DED_NET_MASK)) {
  1084. /* If they have specified a cluster IP address, but no netmask, then fill it in for them. */
  1085. if (!lstrcmpi(paramp->ded_net_mask, CVY_DEF_DED_NET_MASK))
  1086. ParamsGenerateSubnetMask(paramp->ded_ip_addr, paramp->ded_net_mask);
  1087. /* Check for valid dedicated IP address/netmask pairs. */
  1088. if (!IsValidIPAddressSubnetMaskPair(paramp->ded_ip_addr, paramp->ded_net_mask))
  1089. goto error;
  1090. /* Check to make sure that the dedicated netmask is contiguous. */
  1091. if (!IsContiguousSubnetMask(paramp->ded_net_mask))
  1092. goto error;
  1093. }
  1094. /* Check the mac address if the convert_mac flag is not set */
  1095. if ( ! paramp -> i_convert_mac)
  1096. {
  1097. PWCHAR p1, p2;
  1098. WCHAR mac_addr [WLBS_MAX_NETWORK_ADDR + 1];
  1099. DWORD i, j;
  1100. BOOL flag = TRUE;
  1101. _tcscpy (mac_addr, paramp -> cl_mac_addr);
  1102. p2 = p1 = mac_addr;
  1103. for (i = 0 ; i < 6 ; i++)
  1104. {
  1105. if (*p2 == _TEXT('\0'))
  1106. {
  1107. flag = FALSE;
  1108. break;
  1109. }
  1110. j = _tcstoul (p1, &p2, 16);
  1111. if ( j > 255)
  1112. {
  1113. flag = FALSE;
  1114. break;
  1115. }
  1116. if ( ! (*p2 == _TEXT('-') || *p2 == _TEXT(':') || *p2 == _TEXT('\0')) )
  1117. {
  1118. flag = FALSE;
  1119. break;
  1120. }
  1121. if (*p2 == _TEXT('\0') && i < 5)
  1122. {
  1123. flag = FALSE;
  1124. break;
  1125. }
  1126. p1 = p2 + 1;
  1127. p2 = p1;
  1128. }
  1129. if (!flag)
  1130. {
  1131. goto error;
  1132. }
  1133. }
  1134. if (paramp->fIGMPSupport && !paramp->mcast_support)
  1135. {
  1136. //
  1137. // IGMP can not be enabled in unicast mode
  1138. //
  1139. LOG_ERROR("ParamWriteReg IGMP can not be enabled in unicast mode");
  1140. goto error;
  1141. }
  1142. if (paramp->mcast_support && paramp->fIGMPSupport && !paramp->fIpToMCastIp)
  1143. {
  1144. //
  1145. // Multicast mode with IGMP enabled, and user specified an multicast IP address,
  1146. // The multicast IP address should be in the range of (224-239).x.x.x
  1147. // but NOT (224-239).0.0.x or (224-239).128.0.x.
  1148. //
  1149. DWORD dwMCastIp = IpAddressFromAbcdWsz(paramp->szMCastIpAddress);
  1150. if ((dwMCastIp & 0xf0) != 0xe0 ||
  1151. (dwMCastIp & 0x00ffff00) == 0 ||
  1152. (dwMCastIp & 0x00ffff00) == 0x00008000)
  1153. {
  1154. LOG_ERROR1("ParamWriteReg invalid szMCastIpAddressr %ws",
  1155. paramp->szMCastIpAddress);
  1156. goto error;
  1157. }
  1158. }
  1159. #endif // OBSOLETE_CODE
  1160. /* Generate the MAC address. */
  1161. ParamsGenerateMAC(paramp->cl_ip_addr, paramp->cl_mac_addr, paramp->szMCastIpAddress, paramp->i_convert_mac,
  1162. paramp->mcast_support, paramp->fIGMPSupport, paramp->fIpToMCastIp);
  1163. WCHAR reg_path [PARAMS_MAX_STRING_SIZE];
  1164. WCHAR szAdapterGuid[128];
  1165. StringFromGUID2(AdapterGuid, szAdapterGuid,
  1166. sizeof(szAdapterGuid)/sizeof(szAdapterGuid[0]) );
  1167. swprintf (reg_path, L"SYSTEM\\CurrentControlSet\\Services\\WLBS\\Parameters\\Interface\\%s",
  1168. szAdapterGuid);
  1169. status = RegCreateKeyEx (HKEY_LOCAL_MACHINE, reg_path, 0L, L"",
  1170. REG_OPTION_NON_VOLATILE,
  1171. KEY_ALL_ACCESS, NULL, & key, & disp);
  1172. if (status != ERROR_SUCCESS)
  1173. return FALSE;
  1174. swprintf (reg_path, L"%ls", CVY_NAME_INSTALL_DATE);
  1175. size = sizeof (paramp -> install_date);
  1176. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_INSTALL_DATE,
  1177. (LPBYTE) & paramp -> install_date, size);
  1178. if (status != ERROR_SUCCESS)
  1179. goto error;
  1180. swprintf (reg_path, L"%ls", CVY_NAME_VERIFY_DATE);
  1181. size = sizeof (paramp -> i_verify_date);
  1182. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_VERIFY_DATE,
  1183. (LPBYTE) & paramp -> i_verify_date, size);
  1184. if (status != ERROR_SUCCESS)
  1185. goto error;
  1186. swprintf (reg_path, L"%ls", CVY_NAME_VIRTUAL_NIC);
  1187. size = wcslen (paramp -> i_virtual_nic_name) * sizeof (WCHAR);
  1188. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_VIRTUAL_NIC,
  1189. (LPBYTE) & paramp -> i_virtual_nic_name, size);
  1190. if (status != ERROR_SUCCESS)
  1191. goto error;
  1192. swprintf (reg_path, L"%ls", CVY_NAME_HOST_PRIORITY);
  1193. size = sizeof (paramp -> host_priority);
  1194. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_HOST_PRIORITY,
  1195. (LPBYTE) & paramp -> host_priority, size);
  1196. if (status != ERROR_SUCCESS)
  1197. goto error;
  1198. swprintf (reg_path, L"%ls", CVY_NAME_CLUSTER_MODE);
  1199. size = sizeof (paramp -> cluster_mode);
  1200. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_CLUSTER_MODE,
  1201. (LPBYTE) & paramp -> cluster_mode, size);
  1202. if (status != ERROR_SUCCESS)
  1203. goto error;
  1204. swprintf (reg_path, L"%ls", CVY_NAME_NETWORK_ADDR);
  1205. size = wcslen (paramp -> cl_mac_addr) * sizeof (WCHAR);
  1206. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_NETWORK_ADDR,
  1207. (LPBYTE) paramp -> cl_mac_addr, size);
  1208. if (status != ERROR_SUCCESS)
  1209. goto error;
  1210. swprintf (reg_path, L"%ls", CVY_NAME_CL_IP_ADDR);
  1211. size = wcslen (paramp -> cl_ip_addr) * sizeof (WCHAR);
  1212. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_CL_IP_ADDR,
  1213. (LPBYTE) paramp -> cl_ip_addr, size);
  1214. if (status != ERROR_SUCCESS)
  1215. goto error;
  1216. swprintf (reg_path, L"%ls", CVY_NAME_CL_NET_MASK);
  1217. size = wcslen (paramp -> cl_net_mask) * sizeof (WCHAR);
  1218. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_CL_NET_MASK,
  1219. (LPBYTE) paramp -> cl_net_mask, size);
  1220. if (status != ERROR_SUCCESS)
  1221. goto error;
  1222. swprintf (reg_path, L"%ls", CVY_NAME_DED_IP_ADDR);
  1223. size = wcslen (paramp -> ded_ip_addr) * sizeof (WCHAR);
  1224. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_DED_IP_ADDR,
  1225. (LPBYTE) paramp -> ded_ip_addr, size);
  1226. if (status != ERROR_SUCCESS)
  1227. goto error;
  1228. swprintf (reg_path, L"%ls", CVY_NAME_DED_NET_MASK);
  1229. size = wcslen (paramp -> ded_net_mask) * sizeof (WCHAR);
  1230. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_DED_NET_MASK,
  1231. (LPBYTE) paramp -> ded_net_mask, size);
  1232. if (status != ERROR_SUCCESS)
  1233. goto error;
  1234. swprintf (reg_path, L"%ls", CVY_NAME_DOMAIN_NAME);
  1235. size = wcslen (paramp -> domain_name) * sizeof (WCHAR);
  1236. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_DOMAIN_NAME,
  1237. (LPBYTE) paramp -> domain_name, size);
  1238. if (status != ERROR_SUCCESS)
  1239. goto error;
  1240. swprintf (reg_path, L"%ls", CVY_NAME_ALIVE_PERIOD);
  1241. size = sizeof (paramp -> alive_period);
  1242. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_ALIVE_PERIOD,
  1243. (LPBYTE) & paramp -> alive_period, size);
  1244. if (status != ERROR_SUCCESS)
  1245. goto error;
  1246. swprintf (reg_path, L"%ls", CVY_NAME_ALIVE_TOLER);
  1247. size = sizeof (paramp -> alive_tolerance);
  1248. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_ALIVE_TOLER,
  1249. (LPBYTE) & paramp -> alive_tolerance, size);
  1250. if (status != ERROR_SUCCESS)
  1251. goto error;
  1252. swprintf (reg_path, L"%ls", CVY_NAME_NUM_ACTIONS);
  1253. size = sizeof (paramp -> num_actions);
  1254. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_NUM_ACTIONS,
  1255. (LPBYTE) & paramp -> num_actions, size);
  1256. if (status != ERROR_SUCCESS)
  1257. goto error;
  1258. swprintf (reg_path, L"%ls", CVY_NAME_NUM_PACKETS);
  1259. size = sizeof (paramp -> num_packets);
  1260. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_NUM_PACKETS,
  1261. (LPBYTE) & paramp -> num_packets, size);
  1262. if (status != ERROR_SUCCESS)
  1263. goto error;
  1264. swprintf (reg_path, L"%ls", CVY_NAME_NUM_SEND_MSGS);
  1265. size = sizeof (paramp -> num_send_msgs);
  1266. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_NUM_SEND_MSGS,
  1267. (LPBYTE) & paramp -> num_send_msgs, size);
  1268. if (status != ERROR_SUCCESS)
  1269. goto error;
  1270. swprintf (reg_path, L"%ls", CVY_NAME_DSCR_PER_ALLOC);
  1271. size = sizeof (paramp -> dscr_per_alloc);
  1272. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_DSCR_PER_ALLOC,
  1273. (LPBYTE) & paramp -> dscr_per_alloc, size);
  1274. if (status != ERROR_SUCCESS)
  1275. goto error;
  1276. swprintf (reg_path, L"%ls", CVY_NAME_MAX_DSCR_ALLOCS);
  1277. size = sizeof (paramp -> max_dscr_allocs);
  1278. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_MAX_DSCR_ALLOCS,
  1279. (LPBYTE) & paramp -> max_dscr_allocs, size);
  1280. if (status != ERROR_SUCCESS)
  1281. goto error;
  1282. swprintf (reg_path, L"%ls", CVY_NAME_SCALE_CLIENT);
  1283. size = sizeof (paramp -> i_scale_client);
  1284. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_SCALE_CLIENT,
  1285. (LPBYTE) & paramp -> i_scale_client, size);
  1286. if (status != ERROR_SUCCESS)
  1287. goto error;
  1288. swprintf (reg_path, L"%ls", CVY_NAME_CLEANUP_DELAY);
  1289. size = sizeof (paramp -> i_cleanup_delay);
  1290. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_CLEANUP_DELAY,
  1291. (LPBYTE) & paramp -> i_cleanup_delay, size);
  1292. if (status != ERROR_SUCCESS)
  1293. goto error;
  1294. /* V1.1.1 */
  1295. swprintf (reg_path, L"%ls", CVY_NAME_NBT_SUPPORT);
  1296. size = sizeof (paramp -> i_nbt_support);
  1297. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_NBT_SUPPORT,
  1298. (LPBYTE) & paramp -> i_nbt_support, size);
  1299. if (status != ERROR_SUCCESS)
  1300. goto error;
  1301. /* V1.3b */
  1302. swprintf (reg_path, L"%ls", CVY_NAME_MCAST_SUPPORT);
  1303. size = sizeof (paramp -> mcast_support);
  1304. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_MCAST_SUPPORT,
  1305. (LPBYTE) & paramp -> mcast_support, size);
  1306. if (status != ERROR_SUCCESS)
  1307. goto error;
  1308. swprintf (reg_path, L"%ls", CVY_NAME_MCAST_SPOOF);
  1309. size = sizeof (paramp -> i_mcast_spoof);
  1310. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_MCAST_SPOOF,
  1311. (LPBYTE) & paramp -> i_mcast_spoof, size);
  1312. if (status != ERROR_SUCCESS)
  1313. goto error;
  1314. swprintf (reg_path, L"%ls", CVY_NAME_MASK_SRC_MAC);
  1315. size = sizeof (paramp -> mask_src_mac);
  1316. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_MASK_SRC_MAC,
  1317. (LPBYTE) & paramp -> mask_src_mac, size);
  1318. if (status != ERROR_SUCCESS)
  1319. goto error;
  1320. swprintf (reg_path, L"%ls", CVY_NAME_NETMON_ALIVE);
  1321. size = sizeof (paramp -> i_netmon_alive);
  1322. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_NETMON_ALIVE,
  1323. (LPBYTE) & paramp -> i_netmon_alive, size);
  1324. if (status != ERROR_SUCCESS)
  1325. goto error;
  1326. swprintf (reg_path, L"%ls", CVY_NAME_IP_CHG_DELAY);
  1327. size = sizeof (paramp -> i_ip_chg_delay);
  1328. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_IP_CHG_DELAY,
  1329. (LPBYTE) & paramp -> i_ip_chg_delay, size);
  1330. if (status != ERROR_SUCCESS)
  1331. goto error;
  1332. swprintf (reg_path, L"%ls", CVY_NAME_CONVERT_MAC);
  1333. size = sizeof (paramp -> i_convert_mac);
  1334. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_CONVERT_MAC,
  1335. (LPBYTE) & paramp -> i_convert_mac, size);
  1336. if (status != ERROR_SUCCESS)
  1337. goto error;
  1338. swprintf (reg_path, L"%ls", CVY_NAME_NUM_RULES);
  1339. size = sizeof (paramp -> i_num_rules);
  1340. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_NUM_RULES,
  1341. (LPBYTE) & paramp -> i_num_rules, size);
  1342. if (status != ERROR_SUCCESS)
  1343. goto error;
  1344. //
  1345. // sort the rules before writing it to the registry
  1346. // EnumPortRules will take the rules from reg_data and return them in
  1347. // sorted order in the array itself
  1348. //
  1349. WlbsEnumPortRules (paramp, paramp -> i_port_rules, & num_rules);
  1350. ASSERT(paramp -> i_parms_ver == CVY_PARAMS_VERSION); // version should be upgrated in read
  1351. HKEY subkey;
  1352. swprintf (reg_path, L"%ls", CVY_NAME_PORT_RULES);
  1353. // Delete all existing Port Rules
  1354. SHDeleteKey(key, reg_path); // NOT Checking return value cos the key itself may not be present in which case, it will return error
  1355. // Create "PortRules" key
  1356. if (RegCreateKeyEx (key, reg_path, 0L, L"", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, & subkey, & disp)
  1357. != ERROR_SUCCESS)
  1358. goto error;
  1359. bool fSpecificVipPortRuleFound = false;
  1360. idx = 1;
  1361. port_rule = paramp -> i_port_rules;
  1362. while(idx <= num_rules)
  1363. {
  1364. // Invalid port rules are placed at the end, So, once an invalid port rule is encountered, we are done
  1365. if (!port_rule->valid)
  1366. break;
  1367. HKEY rule_key;
  1368. wchar_t idx_str[8];
  1369. // Create the per port-rule key "1", "2", "3", ...etc
  1370. if (RegCreateKeyEx (subkey, _itow(idx, idx_str, 10), 0L, L"", REG_OPTION_NON_VOLATILE,
  1371. KEY_ALL_ACCESS, NULL, & rule_key, & disp)
  1372. != ERROR_SUCCESS)
  1373. goto error;
  1374. // Check if there was any specific-vip port rule
  1375. if (!fSpecificVipPortRuleFound && lstrcmpi(port_rule->virtual_ip_addr, CVY_DEF_ALL_VIP))
  1376. fSpecificVipPortRuleFound = true;
  1377. swprintf (reg_path, L"%ls", CVY_NAME_VIP);
  1378. size = sizeof (port_rule -> virtual_ip_addr);
  1379. status = RegSetValueEx (rule_key, reg_path, 0L, CVY_TYPE_VIP, (LPBYTE) & port_rule->virtual_ip_addr, size);
  1380. if (status != ERROR_SUCCESS)
  1381. {
  1382. goto error;
  1383. }
  1384. swprintf (reg_path, L"%ls", CVY_NAME_START_PORT);
  1385. size = sizeof (port_rule ->start_port );
  1386. status = RegSetValueEx (rule_key, reg_path, 0L, CVY_TYPE_START_PORT, (LPBYTE) &port_rule->start_port, size);
  1387. if (status != ERROR_SUCCESS)
  1388. {
  1389. goto error;
  1390. }
  1391. swprintf (reg_path, L"%ls", CVY_NAME_END_PORT);
  1392. size = sizeof (port_rule ->end_port );
  1393. status = RegSetValueEx (rule_key, reg_path, 0L, CVY_TYPE_END_PORT, (LPBYTE) &port_rule->end_port, size);
  1394. if (status != ERROR_SUCCESS)
  1395. {
  1396. goto error;
  1397. }
  1398. swprintf (reg_path, L"%ls", CVY_NAME_CODE);
  1399. size = sizeof (port_rule ->code);
  1400. status = RegSetValueEx (rule_key, reg_path, 0L, CVY_TYPE_CODE, (LPBYTE) &port_rule->code, size);
  1401. if (status != ERROR_SUCCESS)
  1402. {
  1403. goto error;
  1404. }
  1405. swprintf (reg_path, L"%ls", CVY_NAME_MODE);
  1406. size = sizeof (port_rule->mode);
  1407. status = RegSetValueEx (rule_key, reg_path, 0L, CVY_TYPE_MODE, (LPBYTE) &port_rule->mode, size);
  1408. if (status != ERROR_SUCCESS)
  1409. {
  1410. goto error;
  1411. }
  1412. swprintf (reg_path, L"%ls", CVY_NAME_PROTOCOL);
  1413. size = sizeof (port_rule->protocol);
  1414. status = RegSetValueEx (rule_key, reg_path, 0L, CVY_TYPE_PROTOCOL, (LPBYTE) &port_rule->protocol, size);
  1415. if (status != ERROR_SUCCESS)
  1416. {
  1417. goto error;
  1418. }
  1419. DWORD EqualLoad, Affinity;
  1420. switch (port_rule->mode)
  1421. {
  1422. case CVY_MULTI :
  1423. EqualLoad = port_rule->mode_data.multi.equal_load;
  1424. swprintf (reg_path, L"%ls", CVY_NAME_EQUAL_LOAD );
  1425. size = sizeof (EqualLoad);
  1426. status = RegSetValueEx (rule_key, reg_path, 0L, CVY_TYPE_EQUAL_LOAD, (LPBYTE) &EqualLoad, size);
  1427. if (status != ERROR_SUCCESS)
  1428. {
  1429. goto error;
  1430. }
  1431. Affinity = port_rule->mode_data.multi.affinity;
  1432. swprintf (reg_path, L"%ls", CVY_NAME_AFFINITY );
  1433. size = sizeof (Affinity);
  1434. status = RegSetValueEx (rule_key, reg_path, 0L, CVY_TYPE_AFFINITY, (LPBYTE) &Affinity, size);
  1435. if (status != ERROR_SUCCESS)
  1436. {
  1437. goto error;
  1438. }
  1439. swprintf (reg_path, L"%ls", CVY_NAME_LOAD);
  1440. size = sizeof (port_rule->mode_data.multi.load);
  1441. status = RegSetValueEx (rule_key, reg_path, 0L, CVY_TYPE_LOAD, (LPBYTE) &(port_rule->mode_data.multi.load), size);
  1442. if (status != ERROR_SUCCESS)
  1443. {
  1444. goto error;
  1445. }
  1446. break;
  1447. case CVY_SINGLE :
  1448. swprintf (reg_path, L"%ls", CVY_NAME_PRIORITY);
  1449. size = sizeof (port_rule->mode_data.single.priority);
  1450. status = RegSetValueEx (rule_key, reg_path, 0L, CVY_TYPE_PRIORITY, (LPBYTE) &(port_rule->mode_data.single.priority), size);
  1451. if (status != ERROR_SUCCESS)
  1452. {
  1453. goto error;
  1454. }
  1455. break;
  1456. default:
  1457. break;
  1458. }
  1459. port_rule++;
  1460. idx++;
  1461. }
  1462. // If there is a specific-vip port rule, write that info on to the registry
  1463. if (fSpecificVipPortRuleFound)
  1464. paramp -> i_effective_version = CVY_VERSION_FULL;
  1465. else
  1466. paramp -> i_effective_version = CVY_NT40_VERSION_FULL;
  1467. swprintf (reg_path, L"%ls", CVY_NAME_EFFECTIVE_VERSION);
  1468. size = sizeof (paramp -> i_effective_version);
  1469. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_EFFECTIVE_VERSION,
  1470. (LPBYTE) & paramp -> i_effective_version, size);
  1471. if (status != ERROR_SUCCESS)
  1472. goto error;
  1473. swprintf (reg_path, L"%ls", CVY_NAME_LICENSE_KEY);
  1474. size = wcslen (paramp -> i_license_key) * sizeof (WCHAR);
  1475. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_LICENSE_KEY,
  1476. (LPBYTE) paramp -> i_license_key, size);
  1477. if (status != ERROR_SUCCESS)
  1478. goto error;
  1479. swprintf (reg_path, L"%ls", CVY_NAME_RMT_PASSWORD);
  1480. size = sizeof (paramp -> i_rmt_password);
  1481. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_RMT_PASSWORD,
  1482. (LPBYTE) & paramp -> i_rmt_password, size);
  1483. if (status != ERROR_SUCCESS)
  1484. goto error;
  1485. swprintf (reg_path, L"%ls", CVY_NAME_RCT_PASSWORD);
  1486. size = sizeof (paramp -> i_rct_password);
  1487. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_RCT_PASSWORD,
  1488. (LPBYTE) & paramp -> i_rct_password, size);
  1489. if (status != ERROR_SUCCESS)
  1490. goto error;
  1491. swprintf (reg_path, L"%ls", CVY_NAME_RCT_PORT);
  1492. size = sizeof (paramp -> rct_port);
  1493. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_RCT_PORT,
  1494. (LPBYTE) & paramp -> rct_port, size);
  1495. if (status != ERROR_SUCCESS)
  1496. goto error;
  1497. swprintf (reg_path, L"%ls", CVY_NAME_RCT_ENABLED);
  1498. size = sizeof (paramp -> rct_enabled);
  1499. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_RCT_ENABLED,
  1500. (LPBYTE) & paramp -> rct_enabled, size);
  1501. if (status != ERROR_SUCCESS)
  1502. goto error;
  1503. //
  1504. // IGMP support registry entries
  1505. //
  1506. status = RegSetValueEx (key, CVY_NAME_IGMP_SUPPORT, 0L, CVY_TYPE_IGMP_SUPPORT,
  1507. (LPBYTE) & paramp->fIGMPSupport, sizeof (paramp->fIGMPSupport));
  1508. if (status != ERROR_SUCCESS)
  1509. goto error;
  1510. status = RegSetValueEx (key, CVY_NAME_MCAST_IP_ADDR, 0L, CVY_TYPE_MCAST_IP_ADDR, (LPBYTE) & paramp->szMCastIpAddress,
  1511. lstrlen (paramp->szMCastIpAddress)* sizeof(paramp->szMCastIpAddress[0]));
  1512. if (status != ERROR_SUCCESS)
  1513. goto error;
  1514. status = RegSetValueEx (key, CVY_NAME_IP_TO_MCASTIP, 0L, CVY_TYPE_IP_TO_MCASTIP,
  1515. (LPBYTE) & paramp->fIpToMCastIp, sizeof (paramp->fIpToMCastIp));
  1516. if (status != ERROR_SUCCESS)
  1517. goto error;
  1518. /* If teaming is active on this adapter, then create a subkey to house the BDA teaming configuration and fill it in. */
  1519. if (paramp->bda_teaming.active) {
  1520. GUID TeamGuid;
  1521. HRESULT hr;
  1522. /* Attempt to create the registry key. */
  1523. if (!(bda_key = RegCreateWlbsBDASettings(AdapterGuid)))
  1524. goto error;
  1525. /* Attempt to convert the string to a GUID and check for errors. */
  1526. hr = CLSIDFromString(paramp->bda_teaming.team_id, &TeamGuid);
  1527. /* If the conversion fails, bail out - the team ID must not have been a GUID. */
  1528. if (hr != NOERROR) {
  1529. LOG_ERROR1("ParamWriteReg: Invalid BDA Team ID: %ls", paramp->bda_teaming.team_id);
  1530. goto error;
  1531. }
  1532. /* Set the team ID - if it fails, bail out. */
  1533. status = RegSetValueEx(bda_key, CVY_NAME_BDA_TEAM_ID, 0L, CVY_TYPE_BDA_TEAM_ID, (LPBYTE)&paramp->bda_teaming.team_id,
  1534. lstrlen(paramp->bda_teaming.team_id) * sizeof(paramp->bda_teaming.team_id[0]));
  1535. if (status != ERROR_SUCCESS)
  1536. goto bda_error;
  1537. /* Set the master status - if it fails, bail out. */
  1538. status = RegSetValueEx(bda_key, CVY_NAME_BDA_MASTER, 0L, CVY_TYPE_BDA_MASTER,
  1539. (LPBYTE)&paramp->bda_teaming.master, sizeof (paramp->bda_teaming.master));
  1540. if (status != ERROR_SUCCESS)
  1541. goto bda_error;
  1542. /* Set the reverse hashing flag - if it fails, bail out. */
  1543. status = RegSetValueEx(bda_key, CVY_NAME_BDA_REVERSE_HASH, 0L, CVY_TYPE_BDA_REVERSE_HASH,
  1544. (LPBYTE)&paramp->bda_teaming.reverse_hash, sizeof (paramp->bda_teaming.reverse_hash));
  1545. if (status != ERROR_SUCCESS)
  1546. goto bda_error;
  1547. RegCloseKey(bda_key);
  1548. } else {
  1549. /* Delte the registry key and ignore the return value - the key may not even exist. */
  1550. RegDeleteWlbsBDASettings(AdapterGuid);
  1551. }
  1552. //
  1553. // Create an empty string if VirtualNICName does not exist
  1554. //
  1555. swprintf (reg_path, L"%ls", CVY_NAME_VIRTUAL_NIC);
  1556. WCHAR virtual_nic_name[CVY_MAX_CLUSTER_NIC + 1];
  1557. size = sizeof(virtual_nic_name);
  1558. status = RegQueryValueEx (key, CVY_NAME_VIRTUAL_NIC, 0L, NULL,
  1559. (LPBYTE)virtual_nic_name, & size);
  1560. if (status != ERROR_SUCCESS)
  1561. {
  1562. virtual_nic_name [0] = 0;
  1563. size = wcslen (virtual_nic_name) * sizeof (WCHAR);
  1564. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_VIRTUAL_NIC,
  1565. (LPBYTE) & virtual_nic_name, size);
  1566. }
  1567. /* lastly write the version number */
  1568. swprintf (reg_path, L"%ls", CVY_NAME_VERSION);
  1569. size = sizeof (paramp -> i_parms_ver);
  1570. status = RegSetValueEx (key, reg_path, 0L, CVY_TYPE_VERSION,
  1571. (LPBYTE) & paramp -> i_parms_ver, size);
  1572. if (status != ERROR_SUCCESS)
  1573. goto error;
  1574. RegCloseKey (key);
  1575. return TRUE;
  1576. error:
  1577. RegCloseKey(key);
  1578. return FALSE;
  1579. bda_error:
  1580. RegCloseKey(bda_key);
  1581. goto error;
  1582. }
  1583. //+----------------------------------------------------------------------------
  1584. //
  1585. // Function: ParamDeleteReg
  1586. //
  1587. // Description: Delete the registry settings
  1588. //
  1589. // Arguments: IN const WCHAR* pszInterface -
  1590. //
  1591. // Returns: DWORD WINAPI -
  1592. //
  1593. // History: fengsun Created Header 1/22/00
  1594. //
  1595. //+----------------------------------------------------------------------------
  1596. bool WINAPI ParamDeleteReg(const GUID& AdapterGuid, bool fDeleteObsoleteEntries)
  1597. {
  1598. WCHAR reg_path [PARAMS_MAX_STRING_SIZE];
  1599. LONG status;
  1600. WCHAR szAdapterGuid[128];
  1601. StringFromGUID2(AdapterGuid, szAdapterGuid,
  1602. sizeof(szAdapterGuid)/sizeof(szAdapterGuid[0]) );
  1603. swprintf (reg_path, L"SYSTEM\\CurrentControlSet\\Services\\WLBS\\Parameters\\Interface\\%s",
  1604. szAdapterGuid);
  1605. if (fDeleteObsoleteEntries)
  1606. {
  1607. HKEY hkey;
  1608. // Delete Port Rules in Binary format
  1609. status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, reg_path, 0L, KEY_ALL_ACCESS, &hkey);
  1610. if (status == ERROR_SUCCESS)
  1611. {
  1612. RegDeleteValue(hkey, CVY_NAME_OLD_PORT_RULES);
  1613. RegCloseKey(hkey);
  1614. }
  1615. // Delete Win2k entries, Enumerate & delete values
  1616. swprintf (reg_path, L"SYSTEM\\CurrentControlSet\\Services\\WLBS\\Parameters");
  1617. status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, reg_path, 0L, KEY_ALL_ACCESS, &hkey);
  1618. if (status == ERROR_SUCCESS)
  1619. {
  1620. DWORD Index, ValueNameSize;
  1621. WCHAR ValueName [PARAMS_MAX_STRING_SIZE];
  1622. Index = 0;
  1623. ValueNameSize = PARAMS_MAX_STRING_SIZE;
  1624. while (RegEnumValue(hkey, Index++, ValueName, &ValueNameSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
  1625. {
  1626. RegDeleteValue(hkey, ValueName);
  1627. }
  1628. RegCloseKey(hkey);
  1629. }
  1630. }
  1631. else
  1632. {
  1633. DWORD dwRet = RegDeleteKey(HKEY_LOCAL_MACHINE, reg_path);
  1634. if (dwRet != ERROR_SUCCESS)
  1635. {
  1636. LOG_ERROR1("ParamDeleteReg failed at RegDeleteKey for %s", szAdapterGuid);
  1637. return false;
  1638. }
  1639. }
  1640. return true;
  1641. } /* end Params_delete */
  1642. //+----------------------------------------------------------------------------
  1643. //
  1644. // Function: ParamSetDefaults
  1645. //
  1646. // Description: Set default settings
  1647. //
  1648. // Arguments: PWLBS_REG_PARAMS reg_data -
  1649. //
  1650. // Returns: DWORD -
  1651. //
  1652. // History: fengsun Created Header 3/9/00
  1653. //
  1654. //+----------------------------------------------------------------------------
  1655. DWORD WINAPI ParamSetDefaults(PWLBS_REG_PARAMS reg_data)
  1656. {
  1657. reg_data -> install_date = 0;
  1658. reg_data -> i_verify_date = 0;
  1659. // reg_data -> cluster_nic_name [0] = _TEXT('\0');
  1660. reg_data -> i_parms_ver = CVY_DEF_VERSION;
  1661. reg_data -> i_virtual_nic_name [0] = _TEXT('\0');
  1662. reg_data -> host_priority = CVY_DEF_HOST_PRIORITY;
  1663. reg_data -> cluster_mode = CVY_DEF_CLUSTER_MODE;
  1664. _stprintf (reg_data -> cl_mac_addr, _TEXT("%ls"), CVY_DEF_NETWORK_ADDR);
  1665. _stprintf (reg_data -> cl_ip_addr, _TEXT("%ls"), CVY_DEF_CL_IP_ADDR);
  1666. _stprintf (reg_data -> cl_net_mask, _TEXT("%ls"), CVY_DEF_CL_NET_MASK);
  1667. _stprintf (reg_data -> ded_ip_addr, _TEXT("%ls"), CVY_DEF_DED_IP_ADDR);
  1668. _stprintf (reg_data -> ded_net_mask, _TEXT("%ls"), CVY_DEF_DED_NET_MASK);
  1669. _stprintf (reg_data -> domain_name, _TEXT("%ls"), CVY_DEF_DOMAIN_NAME);
  1670. reg_data -> alive_period = CVY_DEF_ALIVE_PERIOD;
  1671. reg_data -> alive_tolerance = CVY_DEF_ALIVE_TOLER;
  1672. reg_data -> num_actions = CVY_DEF_NUM_ACTIONS;
  1673. reg_data -> num_packets = CVY_DEF_NUM_PACKETS;
  1674. reg_data -> num_send_msgs = CVY_DEF_NUM_SEND_MSGS;
  1675. reg_data -> dscr_per_alloc = CVY_DEF_DSCR_PER_ALLOC;
  1676. reg_data -> max_dscr_allocs = CVY_DEF_MAX_DSCR_ALLOCS;
  1677. reg_data -> i_scale_client = CVY_DEF_SCALE_CLIENT;
  1678. reg_data -> i_cleanup_delay = CVY_DEF_CLEANUP_DELAY;
  1679. reg_data -> i_ip_chg_delay = CVY_DEF_IP_CHG_DELAY;
  1680. reg_data -> i_nbt_support = CVY_DEF_NBT_SUPPORT;
  1681. reg_data -> mcast_support = CVY_DEF_MCAST_SUPPORT;
  1682. reg_data -> i_mcast_spoof = CVY_DEF_MCAST_SPOOF;
  1683. reg_data -> mask_src_mac = CVY_DEF_MASK_SRC_MAC;
  1684. reg_data -> i_netmon_alive = CVY_DEF_NETMON_ALIVE;
  1685. reg_data -> i_effective_version = CVY_NT40_VERSION_FULL;
  1686. reg_data -> i_convert_mac = CVY_DEF_CONVERT_MAC;
  1687. reg_data -> i_num_rules = 0;
  1688. memset (reg_data -> i_port_rules, 0, sizeof (WLBS_PORT_RULE) * WLBS_MAX_RULES);
  1689. _stprintf (reg_data -> i_license_key, _TEXT("%ls"), CVY_DEF_LICENSE_KEY);
  1690. reg_data -> i_rmt_password = CVY_DEF_RMT_PASSWORD;
  1691. reg_data -> i_rct_password = CVY_DEF_RCT_PASSWORD;
  1692. reg_data -> rct_port = CVY_DEF_RCT_PORT;
  1693. reg_data -> rct_enabled = CVY_DEF_RCT_ENABLED;
  1694. reg_data -> i_max_hosts = CVY_MAX_HOSTS;
  1695. reg_data -> i_max_rules = CVY_MAX_USABLE_RULES;
  1696. reg_data -> fIGMPSupport = CVY_DEF_IGMP_SUPPORT;
  1697. lstrcpy(reg_data -> szMCastIpAddress, CVY_DEF_MCAST_IP_ADDR);
  1698. reg_data -> fIpToMCastIp = CVY_DEF_IP_TO_MCASTIP;
  1699. reg_data->bda_teaming.active = CVY_DEF_BDA_ACTIVE;
  1700. reg_data->bda_teaming.master = CVY_DEF_BDA_MASTER;
  1701. reg_data->bda_teaming.reverse_hash = CVY_DEF_BDA_REVERSE_HASH;
  1702. reg_data->bda_teaming.team_id[0] = CVY_DEF_BDA_TEAM_ID;
  1703. reg_data -> i_num_rules = 1;
  1704. // fill in the first port rule.
  1705. _stprintf (reg_data->i_port_rules[0].virtual_ip_addr, _TEXT("%ls"), CVY_DEF_ALL_VIP);
  1706. reg_data -> i_port_rules [0] . start_port = CVY_DEF_PORT_START;
  1707. reg_data -> i_port_rules [0] . end_port = CVY_DEF_PORT_END;
  1708. reg_data -> i_port_rules [0] . valid = TRUE;
  1709. reg_data -> i_port_rules [0] . mode = CVY_DEF_MODE;
  1710. reg_data -> i_port_rules [0] . mode_data . multi . equal_load = TRUE;
  1711. reg_data -> i_port_rules [0] . mode_data . multi . affinity = CVY_DEF_AFFINITY;
  1712. reg_data -> i_port_rules [0] . mode_data . multi . load = CVY_DEF_LOAD;
  1713. reg_data -> i_port_rules [0] . protocol = CVY_DEF_PROTOCOL;
  1714. CVY_RULE_CODE_SET(& reg_data -> i_port_rules [0]);
  1715. return WLBS_OK;
  1716. }
  1717. EXTERN_C DWORD WINAPI WlbsGetNumPortRules
  1718. (
  1719. const PWLBS_REG_PARAMS reg_data
  1720. )
  1721. {
  1722. if (reg_data == NULL)
  1723. return WLBS_BAD_PARAMS;
  1724. return reg_data -> i_num_rules;
  1725. } /* end WlbsGetNumPortRules */
  1726. EXTERN_C DWORD WINAPI WlbsGetEffectiveVersion
  1727. (
  1728. const PWLBS_REG_PARAMS reg_data
  1729. )
  1730. {
  1731. if (reg_data == NULL)
  1732. return WLBS_BAD_PARAMS;
  1733. return reg_data -> i_effective_version;
  1734. } /* end WlbsGetEffectiveVersion */
  1735. EXTERN_C DWORD WINAPI WlbsEnumPortRules
  1736. (
  1737. const PWLBS_REG_PARAMS reg_data,
  1738. PWLBS_PORT_RULE rules,
  1739. PDWORD num_rules
  1740. )
  1741. {
  1742. DWORD count_rules, i, index;
  1743. DWORD lowest_vip, lowest_port;
  1744. BOOL array_flags [WLBS_MAX_RULES];
  1745. WLBS_PORT_RULE sorted_rules [WLBS_MAX_RULES];
  1746. if ((reg_data == NULL) || (num_rules == NULL))
  1747. return WLBS_BAD_PARAMS;
  1748. if (*num_rules == 0)
  1749. rules = NULL;
  1750. /* this array is used for keeping track of which rules have already been retrieved */
  1751. /* This is needed since the rules are to be retrieved in the sorted order */
  1752. memset ( array_flags, 0, sizeof(BOOL) * WLBS_MAX_RULES );
  1753. count_rules = 0;
  1754. while ((count_rules < *num_rules) && (count_rules < reg_data -> i_num_rules))
  1755. {
  1756. i = 0;
  1757. /* find the first rule that has not been retrieved */
  1758. while ((! reg_data -> i_port_rules [i] . valid) || array_flags [i])
  1759. {
  1760. i++;
  1761. }
  1762. lowest_vip = htonl(IpAddressFromAbcdWsz(reg_data -> i_port_rules [i] . virtual_ip_addr));
  1763. lowest_port = reg_data -> i_port_rules [i] . start_port;
  1764. index = i;
  1765. /* Compare that rule with the other non-retrieved rules to get the rule with the
  1766. lowest VIP & start_port */
  1767. i++;
  1768. while (i < WLBS_MAX_RULES)
  1769. {
  1770. if (reg_data -> i_port_rules [i] . valid && ( ! array_flags [i] ))
  1771. {
  1772. DWORD current_vip = htonl(IpAddressFromAbcdWsz(reg_data -> i_port_rules [i] . virtual_ip_addr));
  1773. if ((current_vip < lowest_vip)
  1774. || ((current_vip == lowest_vip) && (reg_data -> i_port_rules [i] . start_port < lowest_port)))
  1775. {
  1776. lowest_vip = current_vip;
  1777. lowest_port = reg_data -> i_port_rules [i] . start_port;
  1778. index = i;
  1779. }
  1780. }
  1781. i++;
  1782. }
  1783. /* The array_flags [i] element is set to TRUE if the rule is retrieved */
  1784. array_flags [index] = TRUE;
  1785. sorted_rules [count_rules] = reg_data -> i_port_rules [index];
  1786. count_rules ++;
  1787. }
  1788. /* write the sorted rules back into the return array */
  1789. for (i = 0; i < count_rules; i++)
  1790. rules[i] = sorted_rules[i];
  1791. /* invalidate the remaining rules in the buffer */
  1792. for (i = count_rules; i < *num_rules; i++)
  1793. rules [i] . valid = FALSE;
  1794. if (*num_rules < reg_data -> i_num_rules)
  1795. {
  1796. *num_rules = reg_data -> i_num_rules;
  1797. return WLBS_TRUNCATED;
  1798. }
  1799. *num_rules = reg_data -> i_num_rules;
  1800. return WLBS_OK;
  1801. } /* end WlbsEnumPortRules */
  1802. EXTERN_C DWORD WINAPI WlbsGetPortRule
  1803. (
  1804. const PWLBS_REG_PARAMS reg_data,
  1805. DWORD vip,
  1806. DWORD pos,
  1807. OUT PWLBS_PORT_RULE rule
  1808. )
  1809. {
  1810. int i;
  1811. if ((reg_data == NULL) || (rule == NULL))
  1812. return WLBS_BAD_PARAMS;
  1813. /* need to check whether pos is within the correct range */
  1814. if ( /* CLEAN_64BIT (pos < CVY_MIN_PORT) || */ (pos > CVY_MAX_PORT))
  1815. return WLBS_BAD_PARAMS;
  1816. /* search through the array for the rules */
  1817. for (i = 0; i < WLBS_MAX_RULES; i++)
  1818. {
  1819. /* check only the valid rules */
  1820. if (reg_data -> i_port_rules[i] . valid == TRUE)
  1821. {
  1822. /* check the range of the rule to see if pos fits into it */
  1823. if ((vip == IpAddressFromAbcdWsz(reg_data -> i_port_rules[i] . virtual_ip_addr)) &&
  1824. (pos >= reg_data -> i_port_rules[i] . start_port) &&
  1825. (pos <= reg_data -> i_port_rules[i] . end_port))
  1826. {
  1827. *rule = reg_data -> i_port_rules [i];
  1828. return WLBS_OK;
  1829. }
  1830. }
  1831. }
  1832. /* no rule was found for this port */
  1833. return WLBS_NOT_FOUND;
  1834. } /* end WlbsGetPortRule */
  1835. EXTERN_C DWORD WINAPI WlbsAddPortRule
  1836. (
  1837. PWLBS_REG_PARAMS reg_data,
  1838. const PWLBS_PORT_RULE rule
  1839. )
  1840. {
  1841. int i;
  1842. DWORD vip;
  1843. if ((reg_data == NULL) || (rule == NULL))
  1844. return WLBS_BAD_PARAMS;
  1845. /* Check if there is space for the new rule */
  1846. if (reg_data -> i_num_rules == WLBS_MAX_RULES)
  1847. return WLBS_MAX_PORT_RULES;
  1848. /* check the rule for valid values */
  1849. /* check for non-zero vip and conflict with dip */
  1850. vip = IpAddressFromAbcdWsz(rule -> virtual_ip_addr);
  1851. if ((vip == 0) || (vip == IpAddressFromAbcdWsz(reg_data->ded_ip_addr)))
  1852. {
  1853. return WLBS_BAD_PORT_PARAMS;
  1854. }
  1855. /* first check the range of the start and end ports */
  1856. if ((rule -> start_port > rule -> end_port) ||
  1857. // CLEAN_64BIT (rule -> start_port < CVY_MIN_PORT) ||
  1858. (rule -> end_port > CVY_MAX_PORT))
  1859. {
  1860. return WLBS_BAD_PORT_PARAMS;
  1861. }
  1862. /* check the protocol range */
  1863. if ((rule -> protocol < CVY_MIN_PROTOCOL) || (rule -> protocol > CVY_MAX_PROTOCOL))
  1864. return WLBS_BAD_PORT_PARAMS;
  1865. /* check filtering mode to see whether it is within range */
  1866. if ((rule -> mode < CVY_MIN_MODE) || (rule -> mode > CVY_MAX_MODE))
  1867. return WLBS_BAD_PORT_PARAMS;
  1868. /* check load weight and affinity if multiple hosts */
  1869. if (rule -> mode == CVY_MULTI)
  1870. {
  1871. if ((rule -> mode_data . multi . affinity < CVY_MIN_AFFINITY) ||
  1872. (rule -> mode_data . multi . affinity > CVY_MAX_AFFINITY))
  1873. {
  1874. return WLBS_BAD_PORT_PARAMS;
  1875. }
  1876. if ((rule -> mode_data . multi . equal_load < CVY_MIN_EQUAL_LOAD) ||
  1877. (rule -> mode_data . multi . equal_load > CVY_MAX_EQUAL_LOAD))
  1878. {
  1879. return WLBS_BAD_PORT_PARAMS;
  1880. }
  1881. if (! rule -> mode_data . multi . equal_load)
  1882. {
  1883. if ((rule -> mode_data . multi . load > CVY_MAX_LOAD))
  1884. //CLEAN_64BIT (rule -> mode_data . multi . load < CVY_MIN_LOAD) ||
  1885. {
  1886. return WLBS_BAD_PORT_PARAMS;
  1887. }
  1888. }
  1889. }
  1890. /* check handling priority range if single host */
  1891. if (rule -> mode == CVY_SINGLE)
  1892. {
  1893. if ((rule -> mode_data . single . priority < CVY_MIN_PRIORITY) ||
  1894. (rule -> mode_data . single . priority > CVY_MAX_PRIORITY))
  1895. {
  1896. return WLBS_BAD_PORT_PARAMS;
  1897. }
  1898. }
  1899. /* go through the rule list and then check for overlapping conditions */
  1900. for (i = 0; i < WLBS_MAX_RULES; i++)
  1901. {
  1902. if (reg_data -> i_port_rules[i] . valid == TRUE)
  1903. {
  1904. if ((IpAddressFromAbcdWsz(reg_data -> i_port_rules[i] . virtual_ip_addr) == vip)
  1905. && (( (reg_data -> i_port_rules[i] . start_port <= rule -> start_port) &&
  1906. (reg_data -> i_port_rules[i] . end_port >= rule -> start_port)) ||
  1907. ( (reg_data -> i_port_rules[i] . start_port >= rule -> start_port) &&
  1908. (reg_data -> i_port_rules[i] . start_port <= rule -> end_port))))
  1909. {
  1910. return WLBS_PORT_OVERLAP;
  1911. }
  1912. }
  1913. }
  1914. /* go through the rule list and find out the first empty spot
  1915. and write out the port rule */
  1916. for (i = 0 ; i < WLBS_MAX_RULES ; i++)
  1917. {
  1918. if (reg_data -> i_port_rules[i] . valid == FALSE)
  1919. {
  1920. reg_data -> i_num_rules ++ ;
  1921. reg_data -> i_port_rules [i] = *rule;
  1922. reg_data -> i_port_rules [i] . valid = TRUE;
  1923. CVY_RULE_CODE_SET(& reg_data -> i_port_rules [i]);
  1924. return WLBS_OK;
  1925. }
  1926. }
  1927. return WLBS_MAX_PORT_RULES;
  1928. } /* end WlbsAddPortRule */
  1929. EXTERN_C DWORD WINAPI WlbsDeletePortRule
  1930. (
  1931. PWLBS_REG_PARAMS reg_data,
  1932. DWORD vip,
  1933. DWORD port
  1934. )
  1935. {
  1936. int i;
  1937. if (reg_data == NULL)
  1938. return WLBS_BAD_PARAMS;
  1939. /* check if the port is within the correct range */
  1940. if ( /* CLEAN_64BIT (port < CVY_MIN_PORT) ||*/ (port > CVY_MAX_PORT))
  1941. return WLBS_BAD_PARAMS;
  1942. /* find the rule associated with this port */
  1943. for (i = 0; i < WLBS_MAX_RULES; i++)
  1944. {
  1945. if (reg_data -> i_port_rules[i] . valid)
  1946. {
  1947. if ((vip == IpAddressFromAbcdWsz(reg_data -> i_port_rules[i] . virtual_ip_addr)) &&
  1948. (port >= reg_data -> i_port_rules[i] . start_port) &&
  1949. (port <= reg_data -> i_port_rules[i] . end_port))
  1950. {
  1951. reg_data -> i_port_rules[i] . valid = FALSE;
  1952. reg_data -> i_num_rules -- ;
  1953. return WLBS_OK;
  1954. }
  1955. }
  1956. }
  1957. return WLBS_NOT_FOUND;
  1958. } /* end WlbsDeletePortRule */
  1959. EXTERN_C DWORD WINAPI WlbsSetRemotePassword
  1960. (
  1961. PWLBS_REG_PARAMS reg_data,
  1962. const WCHAR* password
  1963. )
  1964. {
  1965. if (reg_data == NULL)
  1966. return WLBS_BAD_PARAMS;
  1967. if (password != NULL)
  1968. {
  1969. reg_data -> i_rct_password = License_wstring_encode ((WCHAR*)password);
  1970. }
  1971. else
  1972. reg_data -> i_rct_password = CVY_DEF_RCT_PASSWORD;
  1973. return WLBS_OK;
  1974. } /* end WlbsSetRemotePassword */
  1975. //+----------------------------------------------------------------------------
  1976. //
  1977. // Function: RegChangeNetworkAddress
  1978. //
  1979. // Description: Change the mac address of the adapter in registry
  1980. //
  1981. // Arguments: const GUID& AdapterGuid - the adapter guid to look up settings
  1982. // TCHAR mac_address -
  1983. // BOOL fRemove - true to remove address, false to write address
  1984. //
  1985. // Returns: bool - true if succeeded
  1986. //
  1987. // History: fengsun Created Header 1/18/00
  1988. //
  1989. //+----------------------------------------------------------------------------
  1990. bool WINAPI RegChangeNetworkAddress(const GUID& AdapterGuid, const WCHAR* mac_address, BOOL fRemove)
  1991. {
  1992. HKEY key = NULL;
  1993. LONG status;
  1994. DWORD size;
  1995. DWORD type;
  1996. TCHAR net_addr [CVY_MAX_NETWORK_ADDR + 1];
  1997. HDEVINFO hdi = NULL;
  1998. SP_DEVINFO_DATA deid;
  1999. TCHAR tbuf[CVY_STR_SIZE];
  2000. if (fRemove)
  2001. {
  2002. LOG_INFO("RegChangeNetworkAddress remove mac address");
  2003. }
  2004. else
  2005. {
  2006. if (!lstrcmpi(mac_address, CVY_DEF_UNICAST_NETWORK_ADDR)) {
  2007. LOG_INFO1("RegChangeNetworkAddress refusing to change mac address to %ws", mac_address);
  2008. fRemove = TRUE;
  2009. } else {
  2010. LOG_INFO1("RegChangeNetworkAddress to %ws", mac_address);
  2011. }
  2012. }
  2013. /*
  2014. - write NetworkAddress value into the cluster adapter's params key
  2015. if mac address changed, or remove it if switched to multicast mode
  2016. */
  2017. key = RegOpenWlbsSetting(AdapterGuid, true);
  2018. if (key == NULL)
  2019. {
  2020. LOG_ERROR("RegChangeNetworkAddress failed at RegOpenWlbsSetting");
  2021. goto error;
  2022. }
  2023. _stprintf (tbuf, _TEXT("%ls"), CVY_NAME_CLUSTER_NIC);
  2024. TCHAR driver_name [CVY_STR_SIZE]; // the NIC card name for the cluster
  2025. size = sizeof (driver_name);
  2026. status = RegQueryValueEx (key, tbuf, 0L, & type, (LPBYTE) driver_name,
  2027. & size);
  2028. if (status != ERROR_SUCCESS)
  2029. {
  2030. LOG_ERROR("RegChangeNetworkAddress failed at RegQueryValueEx for ClusterNICName");
  2031. goto error;
  2032. }
  2033. RegCloseKey(key);
  2034. key = NULL;
  2035. hdi = SetupDiCreateDeviceInfoList (&GUID_DEVCLASS_NET, NULL);
  2036. if (hdi == INVALID_HANDLE_VALUE)
  2037. {
  2038. LOG_ERROR("RegChangeNetworkAddress failed at SetupDiCreateDeviceInfoList");
  2039. goto error;
  2040. }
  2041. ZeroMemory(&deid, sizeof(deid));
  2042. deid.cbSize = sizeof(deid);
  2043. if (! SetupDiOpenDeviceInfo (hdi, driver_name, NULL, 0, &deid))
  2044. {
  2045. LOG_ERROR("RegChangeNetworkAddress failed at SetupDiOpenDeviceInfo");
  2046. goto error;
  2047. }
  2048. key = SetupDiOpenDevRegKey (hdi, &deid, DICS_FLAG_GLOBAL, 0,
  2049. DIREG_DRV, KEY_ALL_ACCESS);
  2050. if (key == INVALID_HANDLE_VALUE)
  2051. {
  2052. LOG_ERROR("RegChangeNetworkAddress failed at SetupDiOpenDevRegKey");
  2053. goto error;
  2054. }
  2055. /* Now the key has been obtained and this can be passed to the RegChangeNetworkAddress call */
  2056. if ((/*global_info.mac_addr_change ||*/ !fRemove)) /* a write is required */
  2057. {
  2058. /* Check if the saved name exists.
  2059. * If it does not, create a new field and save the old address.
  2060. * Write the new address and return
  2061. */
  2062. _stprintf (tbuf, _TEXT("%ls"), CVY_NAME_SAVED_NET_ADDR);
  2063. size = sizeof (TCHAR) * CVY_STR_SIZE;
  2064. status = RegQueryValueEx (key, tbuf, 0L, &type,
  2065. (LPBYTE) net_addr, &size);
  2066. if (status != ERROR_SUCCESS) /* there is no saved address. so create a field */
  2067. {
  2068. /* Query the existing mac address in order to save it */
  2069. _stprintf (tbuf, _TEXT("%ls"), CVY_NAME_NET_ADDR);
  2070. size = sizeof (net_addr);
  2071. status = RegQueryValueEx (key, tbuf, 0L, &type,
  2072. (LPBYTE) net_addr, &size);
  2073. if (status != ERROR_SUCCESS) /* create an empty saved address */
  2074. {
  2075. net_addr [0] = 0;
  2076. size = 0;
  2077. }
  2078. _stprintf (tbuf, _TEXT("%ls"), CVY_NAME_SAVED_NET_ADDR);
  2079. status = RegSetValueEx (key, tbuf, 0L, CVY_TYPE_NET_ADDR,
  2080. (LPBYTE) net_addr, size);
  2081. /* Unable to save the old value */
  2082. if (status != ERROR_SUCCESS)
  2083. {
  2084. LOG_ERROR("RegChangeNetworkAddress failed at RegSetValueEx for WLBSSavedNetworkAddress");
  2085. goto error;
  2086. }
  2087. }
  2088. /* Write the new network address */
  2089. _stprintf (tbuf, _TEXT("%ls"), CVY_NAME_NET_ADDR);
  2090. size = _tcslen (mac_address) * sizeof (TCHAR);
  2091. status = RegSetValueEx (key, tbuf, 0L, CVY_TYPE_NET_ADDR,
  2092. (LPBYTE)mac_address, size);
  2093. /* Unable to write the new address */
  2094. if (status != ERROR_SUCCESS)
  2095. {
  2096. LOG_ERROR("RegChangeNetworkAddress failed at RegSetValueEx for NetworkAddress");
  2097. goto error;
  2098. }
  2099. }
  2100. else // remove the address
  2101. {
  2102. /* If the saved field exists,
  2103. * copy this address into the mac address
  2104. * and remove the saved field and return.
  2105. */
  2106. _stprintf (tbuf, _TEXT("%ls"), CVY_NAME_SAVED_NET_ADDR);
  2107. size = sizeof (net_addr);
  2108. status = RegQueryValueEx (key, tbuf, 0L, &type,
  2109. (LPBYTE)net_addr, &size);
  2110. if (status == ERROR_SUCCESS)
  2111. {
  2112. /* delete both fields if saved address is empty */
  2113. if ((size == 0) || (_tcsicmp (net_addr, _TEXT("none")) == 0))
  2114. {
  2115. _stprintf (tbuf, _TEXT("%ls"), CVY_NAME_SAVED_NET_ADDR);
  2116. RegDeleteValue (key, tbuf);
  2117. _stprintf (tbuf, _TEXT("%ls"), CVY_NAME_NET_ADDR);
  2118. RegDeleteValue (key, tbuf);
  2119. }
  2120. else /* copy saved address as the network address and delete the saved address field */
  2121. {
  2122. _stprintf (tbuf, _TEXT("%ls"), CVY_NAME_SAVED_NET_ADDR);
  2123. RegDeleteValue (key, tbuf);
  2124. _stprintf (tbuf, _TEXT("%ls"), CVY_NAME_NET_ADDR);
  2125. size = _tcslen (net_addr) * sizeof (TCHAR);
  2126. status = RegSetValueEx (key, tbuf, 0L, CVY_TYPE_NET_ADDR,
  2127. (LPBYTE) net_addr, size);
  2128. /* Unable to set the original address */
  2129. if (status != ERROR_SUCCESS)
  2130. {
  2131. LOG_ERROR("RegChangeNetworkAddress failed at RegSetValueEx for NetworkAddress");
  2132. goto error;
  2133. }
  2134. }
  2135. }
  2136. }
  2137. RegCloseKey (key);
  2138. key = NULL;
  2139. return true;
  2140. error:
  2141. if (key != NULL)
  2142. RegCloseKey(key);
  2143. if (hdi != NULL)
  2144. SetupDiDestroyDeviceInfoList (hdi);
  2145. LOG_ERROR("RegChangeNetworkAddress failed");
  2146. return false;
  2147. }
  2148. //+----------------------------------------------------------------------------
  2149. //
  2150. // Function: NotifyAdapterAddressChange
  2151. //
  2152. // Description: Notify the adapter to reload MAC address
  2153. // The parameter is different from NotifyAdapterAddressChange.
  2154. // Can not overload, because the function has to be exported
  2155. //
  2156. // Arguments: const WCHAR* driver_name -
  2157. //
  2158. // Returns: void WINAPI -
  2159. //
  2160. // History: fengsun Created 5/20/00
  2161. //
  2162. //+----------------------------------------------------------------------------
  2163. void WINAPI NotifyAdapterAddressChange (const WCHAR * driver_name) {
  2164. NotifyAdapterPropertyChange(driver_name, DICS_PROPCHANGE);
  2165. }
  2166. /*
  2167. * Function: NotifyAdapterPropertyChange
  2168. * Description: Notify a device that a property change event has occurred.
  2169. * Event should be one of: DICS_PROPCHANGE, DICS_DISABLE, DICS_ENABLE
  2170. * Author: shouse 7.17.00
  2171. */
  2172. void WINAPI NotifyAdapterPropertyChange (const WCHAR * driver_name, DWORD eventFlag) {
  2173. HDEVINFO hdi = NULL;
  2174. SP_DEVINFO_DATA deid;
  2175. LOG_INFO1("NotifyAdapterPropertyChange eventFlag %d", eventFlag);
  2176. hdi = SetupDiCreateDeviceInfoList (&GUID_DEVCLASS_NET, NULL);
  2177. if (hdi == INVALID_HANDLE_VALUE)
  2178. {
  2179. LOG_ERROR("NotifyAdapterPropertyChange failed at SetupDiCreateDeviceInfoList");
  2180. goto error;
  2181. }
  2182. ZeroMemory(&deid, sizeof(deid));
  2183. deid.cbSize = sizeof(deid);
  2184. if (! SetupDiOpenDeviceInfo (hdi, driver_name, NULL, 0, &deid))
  2185. {
  2186. LOG_ERROR("NotifyAdapterPropertyChange failed at SetupDiOpenDeviceInfo");
  2187. goto error;
  2188. }
  2189. SP_PROPCHANGE_PARAMS pcp;
  2190. SP_DEVINSTALL_PARAMS deip;
  2191. ZeroMemory(&pcp, sizeof(pcp));
  2192. pcp.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
  2193. pcp.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
  2194. pcp.StateChange = eventFlag;
  2195. pcp.Scope = DICS_FLAG_GLOBAL;
  2196. pcp.HwProfile = 0;
  2197. // Now we set the structure as the device info data's
  2198. // class install params
  2199. if (! SetupDiSetClassInstallParams(hdi, &deid,
  2200. (PSP_CLASSINSTALL_HEADER)(&pcp),
  2201. sizeof(pcp)))
  2202. {
  2203. LOG_ERROR("NotifyAdapterPropertyChange failed at SetupDiSetClassInstallParams");
  2204. goto error;
  2205. }
  2206. // Now we need to set the "we have a class install params" flag
  2207. // in the device install params
  2208. // initialize out parameter and set its cbSize field
  2209. ZeroMemory(&deip, sizeof(SP_DEVINSTALL_PARAMS));
  2210. deip.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
  2211. // get the header
  2212. if (! SetupDiGetDeviceInstallParams(hdi, &deid, &deip))
  2213. {
  2214. LOG_ERROR("NotifyAdapterPropertyChange failed at SetupDiGetDeviceInstallParams");
  2215. goto error;
  2216. }
  2217. deip.Flags |= DI_CLASSINSTALLPARAMS;
  2218. if (! SetupDiSetDeviceInstallParams(hdi, &deid, &deip))
  2219. {
  2220. LOG_ERROR("NotifyAdapterPropertyChange failed at SetupDiGetDeviceInstallParams");
  2221. goto error;
  2222. }
  2223. // Notify the driver that the state has changed
  2224. LOG_INFO("NotifyAdapterPropertyChange, About to call SetupDiCallClassInstaller");
  2225. if (! SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hdi, &deid))
  2226. {
  2227. LOG_ERROR("NotifyAdapterPropertyChange failed at SetupDiCallClassInstaller");
  2228. goto error;
  2229. }
  2230. LOG_INFO("NotifyAdapterPropertyChange, Returned from call to SetupDiCallClassInstaller");
  2231. // Set the properties change flag in the device info to
  2232. // let anyone who cares know that their ui might need
  2233. // updating to reflect any change in the device's status
  2234. // We can't let any failures here stop us so we ignore
  2235. // return values
  2236. SetupDiGetDeviceInstallParams(hdi, &deid, &deip);
  2237. deip.Flags |= DI_PROPERTIES_CHANGE;
  2238. SetupDiSetDeviceInstallParams(hdi, &deid, &deip);
  2239. SetupDiDestroyDeviceInfoList (hdi);
  2240. LOG_INFO("NotifyAdapterPropertyChange succeeded here");
  2241. error:
  2242. if (hdi != NULL)
  2243. SetupDiDestroyDeviceInfoList (hdi);
  2244. }
  2245. /*
  2246. * Function: GetDeviceNameFromGUID
  2247. * Description: Given a GUID, return the driver name.
  2248. * Author: shouse 7.17.00
  2249. */
  2250. void WINAPI GetDriverNameFromGUID (const GUID & AdapterGuid, OUT WCHAR * driver_name, DWORD size) {
  2251. TCHAR tbuf[CVY_STR_SIZE];
  2252. HKEY key = NULL;
  2253. DWORD type;
  2254. if (!(key = RegOpenWlbsSetting(AdapterGuid, true))) return;
  2255. _stprintf (tbuf, _TEXT("%ls"), CVY_NAME_CLUSTER_NIC);
  2256. RegQueryValueEx(key, tbuf, 0L, &type, (LPBYTE)driver_name, &size);
  2257. RegCloseKey(key);
  2258. }
  2259. //+----------------------------------------------------------------------------
  2260. //
  2261. // Function: RegReadAdapterIp
  2262. //
  2263. // Description: Read the adapter IP settings
  2264. //
  2265. // Arguments: const GUID& AdapterGuid -
  2266. // OUT DWORD& dwClusterIp -
  2267. // OUT DWORD& dwDedicatedIp -
  2268. //
  2269. // Returns: bool -
  2270. //
  2271. // History: fengsun Created Header 3/9/00
  2272. //
  2273. //+----------------------------------------------------------------------------
  2274. bool WINAPI RegReadAdapterIp(const GUID& AdapterGuid,
  2275. OUT DWORD& dwClusterIp, OUT DWORD& dwDedicatedIp)
  2276. {
  2277. HKEY key;
  2278. LONG status;
  2279. DWORD size;
  2280. key = RegOpenWlbsSetting(AdapterGuid, true);
  2281. if (key == NULL)
  2282. {
  2283. return false;
  2284. }
  2285. bool local = false;
  2286. TCHAR nic_name[CVY_STR_SIZE]; // Virtual NIC name
  2287. size = sizeof (nic_name);
  2288. status = RegQueryValueEx (key, CVY_NAME_VIRTUAL_NIC, 0L, NULL,
  2289. (LPBYTE) nic_name, & size);
  2290. if (status == ERROR_SUCCESS)
  2291. {
  2292. TCHAR szIpAddress[CVY_STR_SIZE];
  2293. size = sizeof (TCHAR) * CVY_STR_SIZE;
  2294. status = RegQueryValueEx (key, CVY_NAME_CL_IP_ADDR, 0L, NULL,
  2295. (LPBYTE) szIpAddress, & size);
  2296. if (status == ERROR_SUCCESS)
  2297. {
  2298. dwClusterIp = IpAddressFromAbcdWsz (szIpAddress);
  2299. local = true;
  2300. }
  2301. status = RegQueryValueEx (key, CVY_NAME_DED_IP_ADDR, 0L, NULL,
  2302. (LPBYTE) szIpAddress, & size);
  2303. if (status == ERROR_SUCCESS)
  2304. dwDedicatedIp = IpAddressFromAbcdWsz (szIpAddress);
  2305. }
  2306. RegCloseKey (key);
  2307. return local;
  2308. }