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.

1897 lines
59 KiB

  1. /*++
  2. Copyright(c) 1998,99 Microsoft Corporation
  3. Module Name:
  4. control.cpp
  5. Abstract:
  6. Windows Load Balancing Service (WLBS)
  7. Command-line utility
  8. Author:
  9. kyrilf
  10. ramkrish (Post Win2K)
  11. --*/
  12. #include <windows.h>
  13. #include <stdio.h>
  14. #include <conio.h>
  15. #include <stdlib.h>
  16. #include <process.h>
  17. #include <time.h>
  18. #include <locale.h>
  19. #include <winsock2.h>
  20. #include <ws2tcpip.h>
  21. #include <tchar.h>
  22. #include <shlwapi.h>
  23. #define WLBSAPI_INTERNAL_ONLY
  24. #define BACKWARD_COMPATIBILITY
  25. #define CVY_MAX_ADAPTERS 16
  26. #include "wlbsutil.h"
  27. #include "wlbsctrl.h"
  28. #include "wlbsconfig.h"
  29. #include "wlbsparm.h"
  30. #include "wlbsiocl.h"
  31. #define CLIENT
  32. #include "log_msgs.h"
  33. /* CONSTANTS */
  34. #define CVY_OK 1
  35. #define CVY_ERROR_USAGE -1
  36. #define CVY_ERROR_REGISTRY -2
  37. #define CVY_ERROR_SYSTEM -3
  38. #define CVY_ERROR_USER -4
  39. #define CVY_BUF_SIZE 4096
  40. #define CVY_MAX_EVENTS 10
  41. #define CVY_MAX_INSERTS 10
  42. #define CVY_ALL_CLUSTERS 0xffffffff
  43. #define CVY_ALL_HOSTS 0xffffffff
  44. #define CVY_LOCAL_CLUSTER 0
  45. #define CVY_LOCAL_HOST WLBS_LOCAL_HOST
  46. #define TL_ERROR ((DWORD)0x00010000)
  47. #define TL_WARN ((DWORD)0x00020000)
  48. #define TL_INFO ((DWORD)0x00040000)
  49. typedef enum {
  50. mcastipaddress,
  51. iptomcastip,
  52. masksrcmac,
  53. iptomacenable
  54. } WLBS_REG_KEYS;
  55. typedef enum {
  56. query,
  57. suspend,
  58. resume,
  59. __start,
  60. stop,
  61. drainstop,
  62. enable,
  63. disable,
  64. drain,
  65. reload,
  66. display,
  67. ip2mac,
  68. help,
  69. registry,
  70. invalid
  71. } WLBS_COMMANDS;
  72. typedef enum {
  73. TRACE_ALL,
  74. TRACE_FILE,
  75. TRACE_CONSOLE,
  76. TRACE_DEBUGGER
  77. } TraceOutput;
  78. static HANDLE file_hdl = NULL;
  79. static HANDLE ConsoleHdl;
  80. static BYTE buffer [CVY_BUF_SIZE];
  81. static WCHAR message [CVY_BUF_SIZE];
  82. static WCHAR ConsoleBuf [CVY_BUF_SIZE];
  83. static WCHAR wbuf [CVY_STR_SIZE];
  84. static WCHAR psw_buf [CVY_STR_SIZE];
  85. VOID WConsole(const wchar_t *fmt, ...)
  86. {
  87. va_list arglist;
  88. DWORD res1, res2;
  89. DWORD TotalLen;
  90. // Form a string out of the arguments
  91. va_start(arglist, fmt);
  92. wvnsprintf(ConsoleBuf, CVY_BUF_SIZE, fmt, arglist);
  93. va_end(arglist);
  94. // Attempt WriteConsole, if it fails, do a wprintf
  95. TotalLen = lstrlenW(ConsoleBuf);
  96. if (!WriteConsole(ConsoleHdl, ConsoleBuf, lstrlenW(ConsoleBuf), &res1, &res2))
  97. {
  98. wprintf(ConsoleBuf);
  99. }
  100. return;
  101. }
  102. VOID Message_print (DWORD id, ...) {
  103. va_list arglist;
  104. DWORD error;
  105. va_start(arglist, id);
  106. if (FormatMessage(FORMAT_MESSAGE_FROM_HMODULE, NULL, id, 0, message, CVY_BUF_SIZE, & arglist) == 0) {
  107. error = GetLastError();
  108. //
  109. // Can't localize this because we've got a failure trying
  110. // to display a localized message..
  111. //
  112. WConsole(L"Could not print error message due to: ");
  113. if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, message, CVY_BUF_SIZE, NULL) == 0)
  114. WConsole(L"%d\n", error);
  115. else
  116. WConsole(L"\n %ls\n", message);
  117. } else
  118. WConsole(L"%ls", message);
  119. }
  120. VOID Error_print (BOOL sock) {
  121. DWORD error;
  122. if (sock) {
  123. error = WSAGetLastError();
  124. switch (error) {
  125. case WSAENETUNREACH:
  126. Message_print(IDS_CTR_WS_NUNREACH);
  127. break;
  128. case WSAETIMEDOUT:
  129. Message_print(IDS_CTR_WS_TIMEOUT);
  130. break;
  131. case WSAHOST_NOT_FOUND:
  132. Message_print(IDS_CTR_WS_NOAUTH);
  133. break;
  134. case WSATRY_AGAIN:
  135. Message_print(IDS_CTR_WS_NODNS);
  136. break;
  137. case WSAENETDOWN:
  138. Message_print(IDS_CTR_WS_NETFAIL);
  139. break;
  140. case WSAEHOSTUNREACH:
  141. Message_print(IDS_CTR_WS_HUNREACH);
  142. break;
  143. case WSAENETRESET:
  144. Message_print(IDS_CTR_WS_RESET);
  145. break;
  146. default:
  147. Message_print(IDS_CTR_ER_CODE, error);
  148. break;
  149. }
  150. } else {
  151. error = GetLastError();
  152. if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, message, CVY_BUF_SIZE, NULL) == 0)
  153. Message_print(IDS_CTR_ER_CODE, error);
  154. else
  155. WConsole(L"%ls\n", message);
  156. }
  157. }
  158. INT Report (WLBS_COMMANDS command, BOOLEAN condensed, ULONG ret_code, ULONG param1, ULONG param2,
  159. ULONG query_state, ULONG host_id, ULONG host_map) {
  160. ULONG i;
  161. BOOL first;
  162. switch (command) {
  163. case reload:
  164. if (ret_code == WLBS_BAD_PARAMS) {
  165. Message_print(IDS_CTR_BAD_PARAMS);
  166. return CVY_ERROR_USER;
  167. } else
  168. Message_print(IDS_CTR_RELOADED);
  169. break;
  170. case resume:
  171. if (condensed)
  172. if (ret_code == WLBS_ALREADY)
  173. Message_print(IDS_CTR_RESUMED_C_A);
  174. else
  175. Message_print(IDS_CTR_RESUMED_C);
  176. else
  177. if (ret_code == WLBS_ALREADY)
  178. Message_print(IDS_CTR_RESUMED_A);
  179. else
  180. Message_print(IDS_CTR_RESUMED);
  181. break;
  182. case suspend:
  183. if (condensed)
  184. if (ret_code == WLBS_ALREADY)
  185. Message_print(IDS_CTR_SUSPENDED_C_A);
  186. else {
  187. if (ret_code == WLBS_STOPPED)
  188. Message_print(IDS_CTR_FROM_START_C);
  189. Message_print(IDS_CTR_SUSPENDED_C);
  190. }
  191. else
  192. if (ret_code == WLBS_ALREADY)
  193. Message_print(IDS_CTR_SUSPENDED_A);
  194. else {
  195. if (ret_code == WLBS_STOPPED)
  196. Message_print(IDS_CTR_FROM_START);
  197. Message_print(IDS_CTR_SUSPENDED);
  198. }
  199. break;
  200. case __start:
  201. if (ret_code == WLBS_SUSPENDED) {
  202. if (condensed)
  203. Message_print(IDS_CTR_SUSPENDED_C);
  204. else
  205. Message_print(IDS_CTR_SUSPENDED);
  206. return CVY_ERROR_USER;
  207. } else if (ret_code == WLBS_BAD_PARAMS) {
  208. if (condensed)
  209. Message_print(IDS_CTR_BAD_PARAMS_C);
  210. else
  211. Message_print(IDS_CTR_BAD_PARAMS);
  212. return CVY_ERROR_USER;
  213. } else {
  214. if (condensed)
  215. if (ret_code == WLBS_ALREADY)
  216. Message_print(IDS_CTR_STARTED_C_A);
  217. else {
  218. if (ret_code == WLBS_DRAIN_STOP)
  219. Message_print(IDS_CTR_FROM_DRAIN_C);
  220. Message_print(IDS_CTR_STARTED_C);
  221. }
  222. else
  223. if (ret_code == WLBS_ALREADY)
  224. Message_print(IDS_CTR_STARTED_A);
  225. else {
  226. if (ret_code == WLBS_DRAIN_STOP)
  227. Message_print(IDS_CTR_FROM_DRAIN);
  228. Message_print(IDS_CTR_STARTED);
  229. }
  230. }
  231. break;
  232. case stop:
  233. if (ret_code == WLBS_SUSPENDED) {
  234. if (condensed)
  235. Message_print(IDS_CTR_SUSPENDED_C);
  236. else
  237. Message_print(IDS_CTR_SUSPENDED);
  238. return CVY_ERROR_USER;
  239. }else {
  240. if (condensed)
  241. if (ret_code == WLBS_ALREADY)
  242. Message_print(IDS_CTR_STOPPED_C_A);
  243. else
  244. Message_print(IDS_CTR_STOPPED_C);
  245. else
  246. if (ret_code == WLBS_ALREADY)
  247. Message_print(IDS_CTR_STOPPED_A);
  248. else
  249. Message_print(IDS_CTR_STOPPED);
  250. }
  251. break;
  252. case drainstop:
  253. if (ret_code == WLBS_SUSPENDED) {
  254. if (condensed)
  255. Message_print(IDS_CTR_SUSPENDED_C);
  256. else
  257. Message_print(IDS_CTR_SUSPENDED);
  258. return CVY_ERROR_USER;
  259. } else {
  260. if (condensed)
  261. if (ret_code == WLBS_STOPPED)
  262. Message_print(IDS_CTR_STOPPED_C);
  263. else if (ret_code == WLBS_ALREADY)
  264. Message_print(IDS_CTR_DRAINED_C_A);
  265. else
  266. Message_print(IDS_CTR_DRAINED_C);
  267. else
  268. if (ret_code == WLBS_STOPPED)
  269. Message_print(IDS_CTR_STOPPED);
  270. else if (ret_code == WLBS_ALREADY)
  271. Message_print(IDS_CTR_DRAINED_A);
  272. else
  273. Message_print(IDS_CTR_DRAINED);
  274. }
  275. break;
  276. case enable:
  277. case disable:
  278. case drain:
  279. if (ret_code == WLBS_SUSPENDED) {
  280. if (condensed)
  281. Message_print(IDS_CTR_SUSPENDED_C);
  282. else
  283. Message_print(IDS_CTR_SUSPENDED);
  284. return CVY_ERROR_USER;
  285. } else if (ret_code == WLBS_STOPPED) {
  286. if (condensed)
  287. Message_print(IDS_CTR_RLS_ST_C);
  288. else
  289. Message_print(IDS_CTR_RLS_ST);
  290. return CVY_ERROR_USER;
  291. } else if (ret_code == WLBS_NOT_FOUND) {
  292. if (param2 == IOCTL_ALL_PORTS)
  293. {
  294. if (param1 == IOCTL_ALL_VIPS) {
  295. if (condensed)
  296. Message_print(IDS_CTR_RLS_NORULES_C);
  297. else
  298. Message_print(IDS_CTR_RLS_NORULES);
  299. }
  300. else if (param1 == IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP))
  301. {
  302. if (condensed)
  303. Message_print(IDS_CTR_RLS_NO_ALL_VIP_RULES_C);
  304. else
  305. Message_print(IDS_CTR_RLS_NO_ALL_VIP_RULES);
  306. }
  307. else
  308. {
  309. WCHAR szIpAddress[WLBS_MAX_CL_IP_ADDR+1];
  310. AbcdWszFromIpAddress(param1, szIpAddress);
  311. if (condensed)
  312. Message_print(IDS_CTR_RLS_NO_SPECIFIC_VIP_RULES_C, szIpAddress);
  313. else
  314. Message_print(IDS_CTR_RLS_NO_SPECIFIC_VIP_RULES, szIpAddress);
  315. }
  316. }
  317. else
  318. {
  319. if (param1 == IOCTL_ALL_VIPS) {
  320. if (condensed)
  321. Message_print(IDS_CTR_RLS_NONE_C, param2);
  322. else
  323. Message_print(IDS_CTR_RLS_NONE, param2);
  324. }
  325. else if (param1 == IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP))
  326. {
  327. if (condensed)
  328. Message_print(IDS_CTR_RLS_NO_ALL_VIP_RULE_FOR_PORT_C, param2);
  329. else
  330. Message_print(IDS_CTR_RLS_NO_ALL_VIP_RULE_FOR_PORT, param2);
  331. }
  332. else
  333. {
  334. WCHAR szIpAddress[WLBS_MAX_CL_IP_ADDR+1];
  335. AbcdWszFromIpAddress(param1, szIpAddress);
  336. if (condensed)
  337. Message_print(IDS_CTR_RLS_NO_SPECIFIC_VIP_RULE_FOR_PORT_C, szIpAddress, param2);
  338. else
  339. Message_print(IDS_CTR_RLS_NO_SPECIFIC_VIP_RULE_FOR_PORT, szIpAddress, param2);
  340. }
  341. }
  342. return CVY_ERROR_USER;
  343. } else {
  344. switch (command)
  345. {
  346. case enable:
  347. if (condensed)
  348. if (ret_code == WLBS_ALREADY)
  349. Message_print(IDS_CTR_RLS_EN_C_A);
  350. else
  351. Message_print(IDS_CTR_RLS_EN_C);
  352. else
  353. if (ret_code == WLBS_ALREADY)
  354. Message_print(IDS_CTR_RLS_EN_A);
  355. else
  356. Message_print(IDS_CTR_RLS_EN);
  357. break;
  358. case disable:
  359. if (condensed)
  360. if (ret_code == WLBS_ALREADY)
  361. Message_print(IDS_CTR_RLS_DS_C_A);
  362. else
  363. Message_print(IDS_CTR_RLS_DS_C);
  364. else
  365. if (ret_code == WLBS_ALREADY)
  366. Message_print(IDS_CTR_RLS_DS_A);
  367. else
  368. Message_print(IDS_CTR_RLS_DS);
  369. break;
  370. case drain :
  371. if (condensed)
  372. if (ret_code == WLBS_ALREADY)
  373. Message_print(IDS_CTR_RLS_DR_C_A);
  374. else
  375. Message_print(IDS_CTR_RLS_DR_C);
  376. else
  377. if (ret_code == WLBS_ALREADY)
  378. Message_print(IDS_CTR_RLS_DR_A);
  379. else
  380. Message_print(IDS_CTR_RLS_DR);
  381. break;
  382. }
  383. }
  384. break;
  385. case query:
  386. switch (query_state) {
  387. case WLBS_SUSPENDED:
  388. if (condensed)
  389. Message_print(IDS_CTR_CVG_SP_C);
  390. else
  391. Message_print(IDS_CTR_CVG_SP, host_id);
  392. return CVY_OK;
  393. case WLBS_STOPPED:
  394. if (condensed)
  395. Message_print(IDS_CTR_CVG_UN_C);
  396. else
  397. Message_print(IDS_CTR_CVG_UN, host_id);
  398. return CVY_OK;
  399. case WLBS_DISCONNECTED:
  400. if (condensed)
  401. Message_print(IDS_CTR_MEDIA_DISC_C);
  402. else
  403. Message_print(IDS_CTR_MEDIA_DISC, host_id);
  404. return CVY_OK;
  405. case WLBS_DRAINING:
  406. if (condensed)
  407. Message_print(IDS_CTR_CVG_DR_C);
  408. else
  409. Message_print(IDS_CTR_CVG_DR, host_id);
  410. break;
  411. case WLBS_CONVERGING:
  412. if (condensed)
  413. Message_print(IDS_CTR_CVG_PR_C);
  414. else
  415. Message_print(IDS_CTR_CVG_PR, host_id);
  416. break;
  417. case WLBS_CONVERGED:
  418. if (condensed)
  419. Message_print(IDS_CTR_CVG_SL_C);
  420. else
  421. Message_print(IDS_CTR_CVG_SL, host_id);
  422. break;
  423. case WLBS_DEFAULT:
  424. if (condensed)
  425. Message_print(IDS_CTR_CVG_MS_C);
  426. else
  427. Message_print(IDS_CTR_CVG_MS, host_id);
  428. break;
  429. default:
  430. if (condensed)
  431. Message_print(IDS_CTR_CVG_ER_C);
  432. else
  433. Message_print(IDS_CTR_CVG_ER, query_state);
  434. return CVY_ERROR_SYSTEM;
  435. }
  436. if (!condensed) {
  437. first = TRUE;
  438. for (i = 0; i < 32; i ++) {
  439. if (host_map & (1 << i)) {
  440. if (!first)
  441. WConsole (L", ");
  442. else
  443. first = FALSE;
  444. WConsole(L"%d", i + 1);
  445. }
  446. }
  447. WConsole (L"\n");
  448. }
  449. break;
  450. default:
  451. Message_print(IDS_CTR_IO_ER, command);
  452. break;
  453. }
  454. return CVY_OK;
  455. }
  456. INT Display (DWORD cluster) {
  457. HANDLE hdl;
  458. HINSTANCE lib;
  459. DWORD flag;
  460. EVENTLOGRECORD * recp = (EVENTLOGRECORD *)buffer;
  461. DWORD actual, needed, records, index = 0, got = 0;
  462. DWORD j, i, code;
  463. PWCHAR strp;
  464. PWCHAR prot;
  465. WCHAR aff;
  466. time_t curr_time;
  467. PWLBS_PORT_RULE rp, rulep;
  468. BYTE * inserts[CVY_MAX_INSERTS];
  469. WLBS_REG_PARAMS params;
  470. DWORD status;
  471. status = WlbsReadReg(cluster, &params);
  472. if (status != WLBS_OK) {
  473. Message_print (IDS_CTR_REMOTE);
  474. return CVY_ERROR_USER;
  475. }
  476. Message_print(IDS_CTR_DSP_CONFIGURATION);
  477. time (& curr_time);
  478. WConsole(L"%-25.25ls = %ls", L"Current time", _wctime (& curr_time));
  479. WConsole(L"%-25.25ls = %d\n", CVY_NAME_VERSION, params.i_parms_ver);
  480. WConsole(L"%-25.25ls = %ls\n", CVY_NAME_VIRTUAL_NIC, params.i_virtual_nic_name);
  481. WConsole(L"%-25.25ls = %d\n", CVY_NAME_ALIVE_PERIOD, params.alive_period);
  482. WConsole(L"%-25.25ls = %d\n", CVY_NAME_ALIVE_TOLER, params.alive_tolerance);
  483. WConsole(L"%-25.25ls = %d\n", CVY_NAME_NUM_ACTIONS, params.num_actions);
  484. WConsole(L"%-25.25ls = %d\n", CVY_NAME_NUM_PACKETS, params.num_packets);
  485. WConsole(L"%-25.25ls = %d\n", CVY_NAME_NUM_SEND_MSGS, params.num_send_msgs);
  486. WConsole(L"%-25.25ls = %ls\n", CVY_NAME_NETWORK_ADDR, params.cl_mac_addr);
  487. WConsole(L"%-25.25ls = %ls\n", CVY_NAME_DOMAIN_NAME, params.domain_name);
  488. WConsole(L"%-25.25ls = %ls\n", CVY_NAME_CL_IP_ADDR, params.cl_ip_addr);
  489. WConsole(L"%-25.25ls = %ls\n", CVY_NAME_CL_NET_MASK, params.cl_net_mask);
  490. WConsole(L"%-25.25ls = %ls\n", CVY_NAME_DED_IP_ADDR, params.ded_ip_addr);
  491. WConsole(L"%-25.25ls = %ls\n", CVY_NAME_DED_NET_MASK, params.ded_net_mask);
  492. WConsole(L"%-25.25ls = %d\n", CVY_NAME_HOST_PRIORITY, params.host_priority);
  493. WConsole(L"%-25.25ls = %ls\n", CVY_NAME_CLUSTER_MODE, params.cluster_mode ? L"ENABLED" : L"DISABLED");
  494. WConsole(L"%-25.25ls = %d\n", CVY_NAME_DSCR_PER_ALLOC, params.dscr_per_alloc);
  495. WConsole(L"%-25.25ls = %d\n", CVY_NAME_MAX_DSCR_ALLOCS, params.max_dscr_allocs);
  496. WConsole(L"%-25.25ls = %d\n", CVY_NAME_SCALE_CLIENT, params.i_scale_client);
  497. WConsole(L"%-25.25ls = %d\n", CVY_NAME_NBT_SUPPORT, params.i_nbt_support);
  498. WConsole(L"%-25.25ls = %d\n", CVY_NAME_MCAST_SUPPORT, params.mcast_support);
  499. WConsole(L"%-25.25ls = %d\n", CVY_NAME_MCAST_SPOOF, params.i_mcast_spoof);
  500. WConsole(L"%-25.25ls = %d\n", CVY_NAME_MASK_SRC_MAC, params.mask_src_mac);
  501. WConsole(L"%-25.25ls = %ls\n", CVY_NAME_IGMP_SUPPORT, params.fIGMPSupport ? L"ENABLED" : L"DISABLED");
  502. WConsole(L"%-25.25ls = %ls\n", CVY_NAME_IP_TO_MCASTIP, params.fIpToMCastIp ? L"ENABLED" : L"DISABLED");
  503. WConsole(L"%-25.25ls = %ls\n", CVY_NAME_MCAST_IP_ADDR, params.szMCastIpAddress);
  504. WConsole(L"%-25.25ls = %d\n", CVY_NAME_NETMON_ALIVE, params.i_netmon_alive);
  505. if (params.i_effective_version == CVY_NT40_VERSION_FULL)
  506. WConsole(L"%-25.25ls = %ls\n", CVY_NAME_EFFECTIVE_VERSION, CVY_NT40_VERSION);
  507. else
  508. WConsole(L"%-25.25ls = %ls\n", CVY_NAME_EFFECTIVE_VERSION, CVY_VERSION);
  509. WConsole(L"%-25.25ls = %d\n", CVY_NAME_IP_CHG_DELAY, params.i_ip_chg_delay);
  510. WConsole(L"%-25.25ls = %d\n", CVY_NAME_CONVERT_MAC, params.i_convert_mac);
  511. WConsole(L"%-25.25ls = %d\n", CVY_NAME_CLEANUP_DELAY, params.i_cleanup_delay);
  512. WConsole(L"%-25.25ls = %d\n", CVY_NAME_RCT_ENABLED, params.rct_enabled);
  513. WConsole(L"%-25.25ls = %d\n", CVY_NAME_RCT_PORT, params.rct_port);
  514. WConsole(L"%-25.25ls = 0x%X\n", CVY_NAME_RCT_PASSWORD, params.i_rct_password);
  515. WConsole(L"%-25.25ls = 0x%X\n", CVY_NAME_RMT_PASSWORD, params.i_rmt_password);
  516. WConsole(L"%-25.25ls = %ls\n", CVY_NAME_CUR_VERSION, CVY_VERSION);
  517. WConsole(L"%-25.25ls = 0x%X\n", CVY_NAME_INSTALL_DATE, params.install_date);
  518. WConsole(L"%-25.25ls = 0x%X\n", CVY_NAME_VERIFY_DATE, params.i_verify_date);
  519. WConsole(L"%-25.25ls = %d\n", CVY_NAME_NUM_RULES, params.i_num_rules);
  520. WConsole(L"%-25.25ls = %ls\n", CVY_NAME_BDA_TEAMING, params.bda_teaming.active ? L"ENABLED" : L"DISABLED");
  521. WConsole(L"%-25.25ls = %ls\n", CVY_NAME_BDA_TEAM_ID, params.bda_teaming.team_id);
  522. WConsole(L"%-25.25ls = %ls\n", CVY_NAME_BDA_MASTER, params.bda_teaming.master ? L"ENABLED" : L"DISABLED");
  523. WConsole(L"%-25.25ls = %ls\n", CVY_NAME_BDA_REVERSE_HASH, params.bda_teaming.reverse_hash ? L"ENABLED" : L"DISABLED");
  524. WConsole(L"%-25.25ls \n", CVY_NAME_PORT_RULES);
  525. WConsole(L"Virtual IP addr Start\tEnd\tProt\tMode\t\tPri\tLoad\tAffinity\n");
  526. for (i = 0; i < params.i_num_rules; i ++) {
  527. rp = params.i_port_rules + i;
  528. code = CVY_RULE_CODE_GET(rp);
  529. CVY_RULE_CODE_SET(rp);
  530. if (code != CVY_RULE_CODE_GET(rp)) {
  531. WConsole(L"bad rule code 0x%08x vs 0x%08x\n", code, CVY_RULE_CODE_GET(rp));
  532. rp->code = code;
  533. continue;
  534. }
  535. if (!rp->valid) {
  536. WConsole(L"rule is not valid\n");
  537. continue;
  538. }
  539. if (rp->start_port > rp->end_port) {
  540. WConsole(L"bad port range %d-%d\n", rp->start_port, rp->end_port);
  541. continue;
  542. }
  543. for (j = 0; j < i; j ++) {
  544. rulep = params.i_port_rules + j;
  545. if ((IpAddressFromAbcdWsz(rulep->virtual_ip_addr) == IpAddressFromAbcdWsz(rp->virtual_ip_addr))
  546. && ((rulep->start_port < rp->start_port && rulep->end_port >= rp->start_port) ||
  547. (rulep->start_port >= rp->start_port && rulep->start_port <= rp->end_port))) {
  548. WConsole(L"port ranges for rules %d (%d-%d) and %d (%d-%d) overlap\n", i, rp->start_port, rp->end_port, j, rulep->start_port, rulep->end_port);
  549. continue;
  550. }
  551. }
  552. if (rp->start_port > CVY_MAX_PORT) {
  553. WConsole(L"bad start port %d\n", rp->start_port);
  554. continue;
  555. }
  556. if (rp->end_port > CVY_MAX_PORT) {
  557. WConsole(L"bad end port %d\n", rp->end_port);
  558. continue;
  559. }
  560. if (rp->protocol < CVY_MIN_PROTOCOL || rp->protocol > CVY_MAX_PROTOCOL) {
  561. WConsole(L"bad protocol %d\n", rp->protocol);
  562. continue;
  563. }
  564. if (rp->mode < CVY_MIN_MODE || rp->mode > CVY_MAX_MODE) {
  565. WConsole(L"bad mode %d\n", rp->mode);
  566. continue;
  567. }
  568. switch (rp->protocol) {
  569. case CVY_TCP:
  570. prot = L"TCP";
  571. break;
  572. case CVY_UDP:
  573. prot = L"UDP";
  574. break;
  575. default:
  576. prot = L"Both";
  577. break;
  578. }
  579. if (!lstrcmpi(rp->virtual_ip_addr, CVY_DEF_ALL_VIP))
  580. WConsole(L"%15ls\t%5d\t%5d\t%ls\t", L"ALL", rp->start_port, rp->end_port, prot);
  581. else
  582. WConsole(L"%15ls\t%5d\t%5d\t%ls\t", rp->virtual_ip_addr, rp->start_port, rp->end_port, prot);
  583. switch (rp->mode) {
  584. case CVY_SINGLE:
  585. WConsole(L"%-10.10ls\t%2d", L"Single", rp->mode_data.single.priority);
  586. break;
  587. case CVY_MULTI:
  588. if (rp->mode_data.multi.affinity == CVY_AFFINITY_NONE)
  589. aff = L'N';
  590. else if (rp->mode_data.multi.affinity == CVY_AFFINITY_SINGLE)
  591. aff = L'S';
  592. else
  593. aff = L'C';
  594. if (rp->mode_data.multi.equal_load)
  595. WConsole(L"%-10.10ls\t\tEqual\t%lc", L"Multiple", aff);
  596. else {
  597. if (rp->mode_data.multi.load > CVY_MAX_LOAD) {
  598. WConsole(L"bad load %d\n", rp->mode_data.multi.load);
  599. continue;
  600. }
  601. WConsole(L"%-10.10ls\t\t%3d\t%lc", L"Multiple", rp->mode_data.multi.load, aff);
  602. }
  603. break;
  604. default:
  605. WConsole(L"%-10.10ls", L"Disabled");
  606. break;
  607. }
  608. WConsole(L"\n");
  609. }
  610. WConsole(L"\n");
  611. Message_print(IDS_CTR_DSP_EVENTLOG);
  612. hdl = OpenEventLog (NULL, L"System");
  613. if (hdl == NULL) {
  614. WConsole(L"Could not open event log due to:\n");
  615. Error_print (FALSE);
  616. return CVY_ERROR_SYSTEM;
  617. }
  618. if (!GetNumberOfEventLogRecords(hdl, &records)) {
  619. WConsole(L"Could not get number of records in event log due to:\n");
  620. Error_print (FALSE);
  621. CloseEventLog (hdl);
  622. return CVY_ERROR_SYSTEM;
  623. }
  624. if (!GetOldestEventLogRecord (hdl, & index)) {
  625. WConsole(L"Could not get the index of the latest event log record due to:\n");
  626. Error_print (FALSE);
  627. CloseEventLog (hdl);
  628. return CVY_ERROR_SYSTEM;
  629. }
  630. swprintf(message + GetSystemDirectory (message, CVY_BUF_SIZE), L"\\drivers\\%ls.sys", CVY_NAME);
  631. lib = LoadLibrary(message);
  632. if (lib == NULL) {
  633. WConsole(L"Could not load driver image file due to:\n");
  634. Error_print (FALSE);
  635. CloseEventLog (hdl);
  636. return CVY_ERROR_SYSTEM;
  637. }
  638. index += records - 1;
  639. flag = EVENTLOG_SEEK_READ | EVENTLOG_BACKWARDS_READ;
  640. while (got < CVY_MAX_EVENTS && ReadEventLog(hdl, flag, index, recp, CVY_BUF_SIZE, &actual, &needed)) {
  641. while (got < CVY_MAX_EVENTS && actual > 0) {
  642. if (wcscmp ((PWSTR)(((PBYTE) recp) + sizeof(EVENTLOGRECORD)), CVY_NAME) == 0) {
  643. WConsole(L"#%02d ID: 0x%08X Type: %d Category: %d ", index--, recp->EventID, recp->EventType, recp->EventCategory);
  644. time_t TimeGenerated = recp->TimeGenerated;
  645. WConsole(L"Time: %ls", _wctime(&TimeGenerated));
  646. strp = (PWCHAR)((LPBYTE)recp + recp->StringOffset);
  647. for (i = 0; i < CVY_MAX_INSERTS; i ++) {
  648. if (i < recp->NumStrings) {
  649. inserts[i] = (BYTE*)strp;
  650. strp += wcslen (strp) + 1;
  651. } else
  652. inserts[i] = 0;
  653. }
  654. if (FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ARGUMENT_ARRAY, lib,
  655. recp->EventID, 0, (PWCHAR)message, CVY_BUF_SIZE, (va_list *)inserts) == 0) {
  656. WConsole(L"Could not load message string due to:\n");
  657. Error_print(FALSE);
  658. } else
  659. WConsole(L"%ls", message);
  660. for (i = 0; i < recp->DataLength / sizeof(DWORD); i ++) {
  661. if (i != 0 && i % 8 == 0)
  662. WConsole(L"\n");
  663. WConsole(L"%08X ", *(UNALIGNED DWORD*)((PBYTE)recp + recp->DataOffset + i * sizeof(DWORD)));
  664. }
  665. WConsole(L"\n\n");
  666. got++;
  667. }
  668. actual -= recp->Length;
  669. recp = (EVENTLOGRECORD *)((LPBYTE)recp + recp->Length);
  670. index--;
  671. }
  672. recp = (EVENTLOGRECORD *)buffer;
  673. flag = EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ;
  674. }
  675. FreeLibrary(lib);
  676. CloseEventLog(hdl);
  677. Message_print(IDS_CTR_DSP_IPCONFIG);
  678. fflush(stdout);
  679. _wsystem(L"ipconfig /all");
  680. Message_print(IDS_CTR_DSP_STATE);
  681. return CVY_OK;
  682. }
  683. /* This function parses the remaining arguments to determine whether the command
  684. * is for all clusters, or a remote cluster or for a single local cluster. */
  685. BOOLEAN Parse (INT argc, PWCHAR argv [], PINT arg_index, PDWORD ptarget_cl, PDWORD ptarget_host) {
  686. PWCHAR phost;
  687. #ifdef BACKWARD_COMPATIBILITY
  688. *ptarget_cl = CVY_ALL_CLUSTERS;
  689. *ptarget_host = CVY_LOCAL_HOST;
  690. if (*arg_index >= argc)
  691. return TRUE;
  692. #endif
  693. /* At this point, argv[arg_index] == cluster_ip and/or argv[arg_index+1] == /local or /passw or /port */
  694. //
  695. // Special check for /PASSW without a cluster ID, because this is
  696. // a common error
  697. //
  698. if ( _wcsicmp (argv [*arg_index], L"/passw") == 0
  699. || _wcsicmp (argv [*arg_index], L"-passw") == 0)
  700. {
  701. Message_print (IDS_CTR_PSSW_WITHOUT_CLUSTER);
  702. return FALSE;
  703. }
  704. phost = wcschr(argv[* arg_index], L':');
  705. /* if there is no host part - operation applies to all hosts */
  706. if (phost == NULL) {
  707. *ptarget_host = CVY_ALL_HOSTS;
  708. } else {
  709. /* split target name so targ points to cluster name and host to host name */
  710. *phost = 0;
  711. phost ++;
  712. if (wcslen(phost) <= 2 && phost[0] >= L'0' && phost[0] <= L'9' && ((phost[1] >= L'0' && phost[1] <= L'9') || phost[1] == 0))
  713. *ptarget_host = _wtoi(phost);
  714. else {
  715. *ptarget_host = WlbsResolve(phost);
  716. if (*ptarget_host == 0) {
  717. Message_print(IDS_CTR_BAD_HOST_NAME_IP);
  718. return FALSE;
  719. }
  720. }
  721. }
  722. // Retrieve the Cluster IP Address or "ALL"
  723. if (_wcsicmp (argv[*arg_index], L"all") == 0)
  724. {
  725. // If there is a host part, then, cluster ip can not be "ALL"
  726. if (*ptarget_host != CVY_ALL_HOSTS)
  727. {
  728. Message_print(IDS_CTR_BAD_CLUSTER_NAME_IP);
  729. return FALSE;
  730. }
  731. *ptarget_cl = CVY_ALL_CLUSTERS;
  732. }
  733. else
  734. {
  735. *ptarget_cl = WlbsResolve(argv[*arg_index]);
  736. if (*ptarget_cl == 0) {
  737. Message_print(IDS_CTR_BAD_CLUSTER_NAME_IP);
  738. return FALSE;
  739. }
  740. }
  741. (*arg_index)++;
  742. // If there is no host part, then, there better be the LOCAL or GLOBAL flag
  743. if (*ptarget_host == CVY_ALL_HOSTS)
  744. {
  745. if (*arg_index == argc)
  746. {
  747. #ifdef BACKWARD_COMPATIBILITY
  748. return TRUE;
  749. #else
  750. Message_print(IDS_CTR_CLUSTER_WITHOUT_LOCAL_GLOBAL_FLAG);
  751. return FALSE;
  752. #endif
  753. }
  754. if (_wcsicmp (argv[*arg_index], L"local") == 0)
  755. {
  756. *ptarget_host = CVY_LOCAL_HOST;
  757. (*arg_index)++;
  758. }
  759. #ifdef BACKWARD_COMPATIBILITY
  760. else if ((argv[*arg_index][0] == L'/') || (argv[*arg_index][0] == L'-'))
  761. {
  762. if (_wcsicmp(argv[*arg_index] + 1, L"local") == 0)
  763. {
  764. *ptarget_host = CVY_LOCAL_HOST;
  765. (*arg_index)++;
  766. }
  767. }
  768. #endif
  769. else if (_wcsicmp (argv[*arg_index], L"global") == 0)
  770. {
  771. // Already set to CVY_ALL_HOSTS
  772. (*arg_index)++;
  773. }
  774. else
  775. {
  776. Message_print(IDS_CTR_CLUSTER_WITHOUT_LOCAL_GLOBAL_FLAG);
  777. return FALSE;
  778. }
  779. }
  780. if (*arg_index == argc)
  781. return TRUE;
  782. if ((argv[*arg_index][0] == L'/') || (argv[*arg_index][0] == L'-')) {
  783. #ifdef BACKWARD_COMPATIBILITY
  784. if (_wcsicmp(argv[*arg_index] + 1, L"local") == 0) {
  785. (*arg_index)++;
  786. *ptarget_host = CVY_LOCAL_HOST;
  787. return TRUE;
  788. } else
  789. #endif
  790. if ((_wcsicmp(argv[*arg_index] + 1, L"port") == 0) || (_wcsicmp(argv[*arg_index] + 1, L"passw") == 0))
  791. return TRUE;
  792. else
  793. return FALSE;
  794. } else
  795. return FALSE;
  796. }
  797. VOID Process (WLBS_COMMANDS command, DWORD target_cl, DWORD target_host, ULONG param1,
  798. ULONG param2, ULONG dest_port, DWORD dest_addr, PWCHAR dest_password) {
  799. DWORD num_hosts = WLBS_MAX_HOSTS;
  800. DWORD len = WLBS_MAX_CL_IP_ADDR + 1;
  801. DWORD host_map;
  802. WLBS_RESPONSE response[WLBS_MAX_HOSTS];
  803. DWORD status;
  804. DWORD i;
  805. WLBS_REG_PARAMS reg_data;
  806. WlbsPasswordSet(target_cl, dest_password);
  807. WlbsPortSet(target_cl, (USHORT)dest_port);
  808. switch (command) {
  809. case query:
  810. status = WlbsQuery(target_cl, target_host, response, &num_hosts, &host_map, NULL);
  811. break;
  812. case __start:
  813. status = WlbsStart(target_cl, target_host, response, &num_hosts);
  814. break;
  815. case stop:
  816. status = WlbsStop(target_cl, target_host, response, &num_hosts);
  817. break;
  818. case suspend:
  819. status = WlbsSuspend(target_cl, target_host, response, &num_hosts);
  820. break;
  821. case resume:
  822. status = WlbsResume(target_cl, target_host, response, &num_hosts);
  823. break;
  824. case drainstop:
  825. status = WlbsDrainStop(target_cl, target_host, response, &num_hosts);
  826. break;
  827. case enable:
  828. status = WlbsEnable(target_cl, target_host, response, &num_hosts, param1, param2);
  829. break;
  830. case disable:
  831. status = WlbsDisable(target_cl, target_host, response, &num_hosts, param1, param2);
  832. break;
  833. case drain:
  834. status = WlbsDrain(target_cl, target_host, response, &num_hosts, param1, param2);
  835. break;
  836. case reload:
  837. status = WlbsNotifyConfigChange(target_cl);
  838. if (status == WLBS_LOCAL_ONLY) {
  839. Message_print(IDS_CTR_REMOTE);
  840. return;
  841. }
  842. if (status == WLBS_REG_ERROR || status == WLBS_BAD_PARAMS) {
  843. Message_print(IDS_CTR_BAD_PARAMS);
  844. return;
  845. }
  846. if (status == WLBS_OK) {
  847. Message_print(IDS_CTR_RELOADED);
  848. return;
  849. }
  850. break;
  851. case display:
  852. Display(target_cl);
  853. Process(query, target_cl, target_host, param1, param2, dest_port, dest_addr, dest_password);
  854. return;
  855. case registry:
  856. if ((status = WlbsReadReg(target_cl, &reg_data)) != WLBS_OK) {
  857. Message_print(IDS_CTR_REG_READ);
  858. return;
  859. }
  860. switch (param1) {
  861. case mcastipaddress:
  862. reg_data.fIpToMCastIp = FALSE;
  863. WlbsAddressToString(param2, reg_data.szMCastIpAddress, &len);
  864. break;
  865. case iptomcastip:
  866. reg_data.fIpToMCastIp = param2;
  867. break;
  868. case iptomacenable:
  869. reg_data.i_convert_mac = param2;
  870. break;
  871. case masksrcmac:
  872. reg_data.mask_src_mac = param2;
  873. break;
  874. }
  875. if ((status = WlbsWriteReg(target_cl, &reg_data)) != WLBS_OK) {
  876. Message_print(IDS_CTR_REG_WRITE);
  877. return;
  878. }
  879. switch (param1) {
  880. case mcastipaddress:
  881. {
  882. TCHAR igmpaddr[WLBS_MAX_CL_IP_ADDR + 1];
  883. DWORD len = WLBS_MAX_CL_IP_ADDR + 1;
  884. WlbsAddressToString (param2, igmpaddr, &len);
  885. Message_print(IDS_CTR_REG_MCASTIPADDRESS, igmpaddr);
  886. break;
  887. }
  888. case iptomcastip:
  889. Message_print((param2) ? IDS_CTR_REG_IPTOMCASTIP_ON : IDS_CTR_REG_IPTOMCASTIP_OFF);
  890. break;
  891. case masksrcmac:
  892. Message_print((param2) ? IDS_CTR_REG_MASKSRCMAC_ON : IDS_CTR_REG_MASKSRCMAC_OFF);
  893. break;
  894. case iptomacenable:
  895. Message_print((param2) ? IDS_CTR_REG_IPTOMACENABLE_ON : IDS_CTR_REG_IPTOMACENABLE_OFF);
  896. break;
  897. }
  898. return;
  899. default:
  900. return;
  901. }
  902. if (status == WLBS_INIT_ERROR) {
  903. Message_print(IDS_CTR_INIT);
  904. return;
  905. }
  906. if (status == WLBS_LOCAL_ONLY) {
  907. Message_print(IDS_CTR_WSOCK);
  908. return;
  909. }
  910. if (status == WLBS_REMOTE_ONLY) {
  911. Message_print(IDS_CTR_NO_CVY, CVY_NAME);
  912. return;
  913. }
  914. if (status >= WSABASEERR) {
  915. Message_print(IDS_CTR_WSOCK);
  916. Error_print(TRUE);
  917. return;
  918. }
  919. if (status == WLBS_TIMEOUT) {
  920. Message_print(IDS_CTR_NO_RSP3);
  921. if (command != query)
  922. Message_print(IDS_CTR_NO_RSP4, CVY_NAME);
  923. return;
  924. }
  925. if (target_host == CVY_LOCAL_HOST) {
  926. Report(command, FALSE, status, param1, param2, response[0].status, response[0].id, host_map);
  927. return;
  928. }
  929. /* Call Report for each host's response */
  930. for (i = 0; i < num_hosts; i++) {
  931. if (response[i].address == 0)
  932. Message_print(IDS_CTR_HOST_NO_DED, response [i] . id);
  933. else {
  934. DWORD len = CVY_STR_SIZE;
  935. #if defined (SBH)
  936. Message_print(IDS_CTR_HOST, response[i].id, response[i].hostname);
  937. #else
  938. WlbsAddressToString(response[i].address, wbuf, &len);
  939. Message_print(IDS_CTR_HOST, response[i].id, wbuf);
  940. #endif
  941. }
  942. if (response[i].status == WLBS_BAD_PASSW) {
  943. if (target_host != CVY_ALL_HOSTS) {
  944. WConsole(L"\n");
  945. Message_print(IDS_CTR_BAD_PASSW);
  946. } else {
  947. Message_print(IDS_CTR_BAD_PASSW_C);
  948. WConsole(L"\n");
  949. }
  950. continue;
  951. }
  952. Report(command, TRUE, response[i].status, param1, param2, response[i].status, response[i].id, host_map);
  953. }
  954. return;
  955. }
  956. BOOL
  957. ParsePort(
  958. PWCHAR arg,
  959. PULONG pvip,
  960. PULONG pport
  961. )
  962. /*
  963. arg is expected to optionally contain a virtual IP address or a
  964. "all", signifying the "all vip" port rule and mandatorilay contain
  965. "all", signifying all ports, or a port number in the range of 0-65535.
  966. Return: TRUE if valid parse, in which case *pvip & *pport contains the parsed
  967. value. FALSE if invalid parse, in which case *pvip & *pport are undefined.
  968. */
  969. {
  970. BOOL fRet = TRUE;
  971. WCHAR vip_str[WLBS_MAX_CL_IP_ADDR+1];
  972. WCHAR *temp_str;
  973. ULONG port, viplen;
  974. // Check if a vip or the "ALL" string was passed
  975. if ((temp_str = wcspbrk(arg,L":")) != NULL)
  976. {
  977. viplen = (ULONG)(temp_str - arg);
  978. wcsncpy(vip_str, arg, viplen);
  979. vip_str[viplen] = L'\0';
  980. *pvip = IpAddressFromAbcdWsz(vip_str);
  981. // A vip was not passed, Check if the "All" string was passed
  982. if (*pvip == INADDR_NONE)
  983. {
  984. if (_wcsicmp (vip_str, L"all") == 0)
  985. {
  986. *pvip = IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP);
  987. }
  988. else
  989. {
  990. return FALSE;
  991. }
  992. }
  993. arg = temp_str + 1;
  994. }
  995. else // Neither a vip nor the "All" string was passed, so this applies to every vip
  996. {
  997. *pvip = IOCTL_ALL_VIPS;
  998. }
  999. if (_wcsicmp (arg, L"all") == 0)
  1000. {
  1001. port = IOCTL_ALL_PORTS;
  1002. }
  1003. else
  1004. {
  1005. port = _wtoi (arg);
  1006. if ( wcspbrk(arg, L".:") != NULL
  1007. || (port == 0 && arg[0] != L'0')
  1008. || port > 65535
  1009. )
  1010. fRet = FALSE;
  1011. }
  1012. *pport = port;
  1013. return fRet;
  1014. }
  1015. /*
  1016. * Function: Process_tracing
  1017. * Description: This function processing the tracing command.
  1018. * Author: shouse 12.12.00
  1019. *
  1020. */
  1021. DWORD Process_tracing (DWORD tracing, TraceOutput output, DWORD flags) {
  1022. HKEY hTracingKey;
  1023. const WCHAR szTracingKey[] = L"Software\\Microsoft\\Tracing\\wlbs";
  1024. const WCHAR szDebuggerTracingEnableValue[] = L"EnableDebuggerTracing";
  1025. const WCHAR szDebuggerTracingMaskValue[] = L"DebuggerTracingMask";
  1026. const WCHAR szFileTracingEnableValue[] = L"EnableFileTracing";
  1027. const WCHAR szFileTracingMaskValue[] = L"FileTracingMask";
  1028. const WCHAR szConsoleTracingEnableValue[] = L"EnableConsoleTracing";
  1029. const WCHAR szConsoleTracingMaskValue[] = L"ConsoleTracingMask";
  1030. DWORD status = ERROR_SUCCESS;
  1031. if ((status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szTracingKey, 0, KEY_ALL_ACCESS, &hTracingKey)) == ERROR_SUCCESS) {
  1032. DWORD size = sizeof (DWORD);
  1033. switch (output) {
  1034. case TRACE_FILE:
  1035. if ((status = RegSetValueEx(hTracingKey, szFileTracingEnableValue, 0, REG_DWORD, (LPBYTE)&tracing, size)) != ERROR_SUCCESS)
  1036. break;
  1037. if (tracing)
  1038. if ((status = RegSetValueEx(hTracingKey, szFileTracingMaskValue, 0, REG_DWORD, (LPBYTE)&flags, size)) != ERROR_SUCCESS)
  1039. break;
  1040. break;
  1041. case TRACE_CONSOLE:
  1042. if ((status = RegSetValueEx(hTracingKey, szConsoleTracingEnableValue, 0, REG_DWORD, (LPBYTE)&tracing, size)) != ERROR_SUCCESS)
  1043. break;
  1044. if (tracing)
  1045. if ((status = RegSetValueEx(hTracingKey, szConsoleTracingMaskValue, 0, REG_DWORD, (LPBYTE)&flags, size)) != ERROR_SUCCESS)
  1046. break;
  1047. break;
  1048. case TRACE_DEBUGGER:
  1049. if ((status = RegSetValueEx(hTracingKey, szDebuggerTracingEnableValue, 0, REG_DWORD, (LPBYTE)&tracing, size)) != ERROR_SUCCESS)
  1050. break;
  1051. if (tracing)
  1052. if ((status = RegSetValueEx(hTracingKey, szDebuggerTracingMaskValue, 0, REG_DWORD, (LPBYTE)&flags, size)) != ERROR_SUCCESS)
  1053. break;
  1054. break;
  1055. case TRACE_ALL:
  1056. if ((status = RegSetValueEx(hTracingKey, szFileTracingEnableValue, 0, REG_DWORD, (LPBYTE)&tracing, size)) != ERROR_SUCCESS)
  1057. break;
  1058. if (tracing)
  1059. if ((status = RegSetValueEx(hTracingKey, szFileTracingMaskValue, 0, REG_DWORD, (LPBYTE)&flags, size)) != ERROR_SUCCESS)
  1060. break;
  1061. if ((status = RegSetValueEx(hTracingKey, szConsoleTracingEnableValue, 0, REG_DWORD, (LPBYTE)&tracing, size)) != ERROR_SUCCESS)
  1062. break;
  1063. if (tracing)
  1064. if ((status = RegSetValueEx(hTracingKey, szConsoleTracingMaskValue, 0, REG_DWORD, (LPBYTE)&flags, size)) != ERROR_SUCCESS)
  1065. break;
  1066. if ((status = RegSetValueEx(hTracingKey, szDebuggerTracingEnableValue, 0, REG_DWORD, (LPBYTE)&tracing, size)) != ERROR_SUCCESS)
  1067. break;
  1068. if (tracing)
  1069. if ((status = RegSetValueEx(hTracingKey, szDebuggerTracingMaskValue, 0, REG_DWORD, (LPBYTE)&flags, size)) != ERROR_SUCCESS)
  1070. break;
  1071. break;
  1072. }
  1073. RegCloseKey(hTracingKey);
  1074. }
  1075. if (status == ERROR_SUCCESS) {
  1076. switch (output) {
  1077. case TRACE_FILE:
  1078. if (tracing)
  1079. Message_print(IDS_CTR_TRACE_FILE_ON);
  1080. else
  1081. Message_print(IDS_CTR_TRACE_FILE_OFF);
  1082. break;
  1083. case TRACE_CONSOLE:
  1084. if (tracing)
  1085. Message_print(IDS_CTR_TRACE_CONSOLE_ON);
  1086. else
  1087. Message_print(IDS_CTR_TRACE_CONSOLE_OFF);
  1088. break;
  1089. case TRACE_DEBUGGER:
  1090. if (tracing)
  1091. Message_print(IDS_CTR_TRACE_DEBUGGER_ON);
  1092. else
  1093. Message_print(IDS_CTR_TRACE_DEBUGGER_OFF);
  1094. break;
  1095. case TRACE_ALL:
  1096. if (tracing)
  1097. Message_print(IDS_CTR_TRACE_ALL_ON);
  1098. else
  1099. Message_print(IDS_CTR_TRACE_ALL_OFF);
  1100. break;
  1101. }
  1102. if (tracing) {
  1103. switch (flags) {
  1104. case TL_ERROR:
  1105. Message_print(IDS_CTR_TRACE_E);
  1106. break;
  1107. case TL_WARN:
  1108. Message_print(IDS_CTR_TRACE_W);
  1109. break;
  1110. case TL_INFO:
  1111. Message_print(IDS_CTR_TRACE_I);
  1112. break;
  1113. case TL_ERROR|TL_INFO:
  1114. Message_print(IDS_CTR_TRACE_EI);
  1115. break;
  1116. case TL_ERROR|TL_WARN:
  1117. Message_print(IDS_CTR_TRACE_EW);
  1118. break;
  1119. case TL_WARN|TL_INFO:
  1120. Message_print(IDS_CTR_TRACE_WI);
  1121. break;
  1122. case TL_ERROR|TL_WARN|TL_INFO:
  1123. Message_print(IDS_CTR_TRACE_EWI);
  1124. break;
  1125. }
  1126. }
  1127. }
  1128. return status;
  1129. }
  1130. /*
  1131. * Function: Parse_tracing
  1132. * Description: This function parses the WLBS tracing control arguments.
  1133. * Author: shouse 12.12.00
  1134. *
  1135. */
  1136. BOOLEAN Parse_tracing (INT argc, PWCHAR argv [], PINT arg_index, PDWORD flags) {
  1137. if (argc < 4) return TRUE;
  1138. for (; (*arg_index) < argc; (*arg_index)++) {
  1139. if ((_wcsicmp(argv[*arg_index] + 1, L"error") == 0)) {
  1140. if (*(argv[*arg_index]) == '+')
  1141. *flags |= TL_ERROR;
  1142. else if (*(argv[*arg_index]) == '-')
  1143. *flags &= ~TL_ERROR;
  1144. else
  1145. return FALSE;
  1146. } else if ((_wcsicmp(argv[*arg_index] + 1, L"warning") == 0)) {
  1147. if (*(argv[*arg_index]) == '+')
  1148. *flags |= TL_WARN;
  1149. else if (*(argv[*arg_index]) == '-')
  1150. *flags &= ~TL_WARN;
  1151. else
  1152. return FALSE;
  1153. } else if ((_wcsicmp(argv[*arg_index] + 1, L"info") == 0)) {
  1154. if (*(argv[*arg_index]) == '+')
  1155. *flags |= TL_INFO;
  1156. else if (*(argv[*arg_index]) == '-')
  1157. *flags &= ~TL_INFO;
  1158. else
  1159. return FALSE;
  1160. } else
  1161. return FALSE;
  1162. }
  1163. return TRUE;
  1164. }
  1165. extern "C"
  1166. {
  1167. int __cdecl wmain (int argc, PWCHAR argv[]) {
  1168. INT arg_index;
  1169. ULONG i, ip;
  1170. PUCHAR bp;
  1171. LONG status;
  1172. DWORD target_cl;
  1173. DWORD target_host;
  1174. WLBS_COMMANDS command = invalid;
  1175. ULONG param1;
  1176. ULONG param2;
  1177. ULONG dest_port;
  1178. PWCHAR dest_password;
  1179. DWORD dest_addr;
  1180. _wsetlocale(LC_ALL, L".OCP");
  1181. if ((ConsoleHdl = GetStdHandle(STD_OUTPUT_HANDLE)) == INVALID_HANDLE_VALUE)
  1182. {
  1183. wprintf(L"GetStdHandle failed, Unable to write to Console !!!\n");
  1184. return CVY_ERROR_SYSTEM;
  1185. }
  1186. Message_print(IDS_CTR_NAME, CVY_NAME);
  1187. if (argc < 2 || argc > 10) {
  1188. usage:
  1189. Message_print(IDS_CTR_USAGE, CVY_NAME);
  1190. Message_print(IDS_CTR_USAGE2);
  1191. return CVY_ERROR_USAGE;
  1192. }
  1193. status = WlbsInit(NULL, WLBS_API_VER, NULL);
  1194. if (status == WLBS_INIT_ERROR) {
  1195. Message_print(IDS_CTR_WSOCK);
  1196. Error_print(TRUE);
  1197. return CVY_ERROR_SYSTEM;
  1198. }
  1199. #if defined (SBH)
  1200. /* 100 BEGIN hack. */
  1201. IOCTL_QUERY_STATE buf;
  1202. buf.Operation = NLB_QUERY_PACKET_FILTER;
  1203. buf.Filter.ServerIPAddress = WlbsResolve(L"12.12.4.2");
  1204. buf.Filter.ClientIPAddress = WlbsResolve(L"11.11.1.1");
  1205. buf.Filter.ServerPort = 80;
  1206. buf.Filter.ClientPort = 17348;
  1207. buf.Filter.Protocol = 6;
  1208. DWORD myretval = WlbsQueryState(WlbsResolve(L"12.12.4.2"), CVY_ALL_HOSTS, &buf);
  1209. return CVY_OK;;
  1210. /* 110 END hack. */
  1211. #endif
  1212. arg_index = 1;
  1213. /* parse command */
  1214. if (_wcsicmp(argv [arg_index], L"ip2mac") == 0) {
  1215. command = ip2mac;
  1216. arg_index++;
  1217. if (argc < 3)
  1218. goto usage;
  1219. ip = WlbsResolve(argv[arg_index]);
  1220. bp = (PUCHAR)(&ip);
  1221. Message_print(IDS_CTR_IP, inet_ntoa(*((struct in_addr *)&ip)));
  1222. Message_print(IDS_CTR_MCAST, bp[0], bp[1], bp[2], bp[3]);
  1223. Message_print(IDS_CTR_UCAST, bp[0], bp[1], bp[2], bp[3]);
  1224. return CVY_OK;
  1225. } else if (_wcsicmp(argv[arg_index], L"help") == 0) {
  1226. command = help;
  1227. swprintf(wbuf, L"%ls.chm", CVY_NAME);
  1228. if (_wspawnlp(P_NOWAIT, L"hh.exe", L"hh.exe", wbuf, NULL) == -1) {
  1229. Message_print(IDS_CTR_HELP);
  1230. return CVY_ERROR_SYSTEM;
  1231. }
  1232. return CVY_OK;
  1233. } else if (_wcsicmp(argv[arg_index], L"suspend") == 0) {
  1234. command = suspend;
  1235. arg_index++;
  1236. #ifndef BACKWARD_COMPATIBILITY
  1237. if (argc < 3)
  1238. goto usage;
  1239. #endif
  1240. if (!Parse(argc, argv, &arg_index, &target_cl, &target_host))
  1241. goto usage;
  1242. } else if (_wcsicmp(argv[arg_index], L"resume") == 0) {
  1243. command = resume;
  1244. arg_index++;
  1245. #ifndef BACKWARD_COMPATIBILITY
  1246. if (argc < 3)
  1247. goto usage;
  1248. #endif
  1249. if (!Parse(argc, argv, &arg_index, &target_cl, &target_host))
  1250. goto usage;
  1251. } else if (_wcsicmp(argv[arg_index], L"start") == 0) {
  1252. command = __start;
  1253. arg_index++;
  1254. #ifndef BACKWARD_COMPATIBILITY
  1255. if (argc < 3)
  1256. goto usage;
  1257. #endif
  1258. if (!Parse(argc, argv, &arg_index, &target_cl, &target_host))
  1259. goto usage;
  1260. } else if (_wcsicmp(argv[arg_index], L"stop") == 0) {
  1261. command = stop;
  1262. arg_index++;
  1263. #ifndef BACKWARD_COMPATIBILITY
  1264. if (argc < 3)
  1265. goto usage;
  1266. #endif
  1267. if (!Parse(argc, argv, &arg_index, &target_cl, &target_host))
  1268. goto usage;
  1269. } else if (_wcsicmp(argv[arg_index], L"drainstop") == 0) {
  1270. command = drainstop;
  1271. arg_index++;
  1272. #ifndef BACKWARD_COMPATIBILITY
  1273. if (argc < 3)
  1274. goto usage;
  1275. #endif
  1276. if (!Parse(argc, argv, &arg_index, &target_cl, &target_host))
  1277. goto usage;
  1278. } else if (_wcsicmp(argv[arg_index], L"query") == 0) {
  1279. command = query;
  1280. arg_index++;
  1281. #ifndef BACKWARD_COMPATIBILITY
  1282. if (argc < 3)
  1283. goto usage;
  1284. #endif
  1285. if (!Parse(argc, argv, &arg_index, &target_cl, &target_host))
  1286. goto usage;
  1287. } else if (_wcsicmp(argv[arg_index], L"enable") == 0) {
  1288. command = enable;
  1289. arg_index++;
  1290. #ifdef BACKWARD_COMPATIBILITY
  1291. if (argc < 3)
  1292. #else
  1293. if (argc < 4)
  1294. #endif
  1295. goto usage;
  1296. if (!ParsePort(argv[arg_index], &param1, &param2))
  1297. goto usage;
  1298. arg_index++;
  1299. if (!Parse(argc, argv, &arg_index, &target_cl, &target_host))
  1300. goto usage;
  1301. } else if (_wcsicmp(argv[arg_index], L"disable") == 0) {
  1302. command = disable;
  1303. arg_index++;
  1304. #ifdef BACKWARD_COMPATIBILITY
  1305. if (argc < 3)
  1306. #else
  1307. if (argc < 4)
  1308. #endif
  1309. goto usage;
  1310. if (!ParsePort(argv[arg_index], &param1, &param2))
  1311. goto usage;
  1312. arg_index++;
  1313. if (!Parse(argc, argv, &arg_index, &target_cl, &target_host))
  1314. goto usage;
  1315. } else if (_wcsicmp(argv[arg_index], L"drain") == 0) {
  1316. command = drain;
  1317. arg_index++;
  1318. #ifdef BACKWARD_COMPATIBILITY
  1319. if (argc < 3)
  1320. #else
  1321. if (argc < 4)
  1322. #endif
  1323. goto usage;
  1324. if (!ParsePort(argv[arg_index], &param1, &param2))
  1325. goto usage;
  1326. arg_index++;
  1327. if (!Parse(argc, argv, &arg_index, &target_cl, &target_host))
  1328. goto usage;
  1329. }
  1330. /* local only commands */
  1331. else if (_wcsicmp(argv[arg_index], L"display") == 0) {
  1332. command = display;
  1333. arg_index++;
  1334. target_host = CVY_LOCAL_HOST;
  1335. // Verify that the cluster ip or "All" string is passed and there are no more arguments
  1336. if ((arg_index == argc) || (arg_index + 1 < argc))
  1337. #ifdef BACKWARD_COMPATIBILITY
  1338. if (arg_index == argc)
  1339. target_cl = CVY_ALL_CLUSTERS;
  1340. else
  1341. goto usage;
  1342. #else
  1343. goto usage;
  1344. #endif
  1345. else {
  1346. // Retrieve the Cluster IP Address or "ALL"
  1347. if (_wcsicmp (argv[arg_index], L"all") == 0)
  1348. {
  1349. target_cl = CVY_ALL_CLUSTERS;
  1350. }
  1351. else
  1352. {
  1353. target_cl = WlbsResolve(argv [arg_index]);
  1354. if (target_cl == 0)
  1355. goto usage;
  1356. }
  1357. arg_index++;
  1358. }
  1359. } else if (_wcsicmp(argv[arg_index], L"reload") == 0) {
  1360. command = reload;
  1361. arg_index++;
  1362. target_host = CVY_LOCAL_HOST;
  1363. // Verify that the cluster ip or "All" string is passed and there are no more arguments
  1364. if ((arg_index == argc) || (arg_index + 1 < argc))
  1365. #ifdef BACKWARD_COMPATIBILITY
  1366. if (arg_index == argc)
  1367. target_cl = CVY_ALL_CLUSTERS;
  1368. else
  1369. goto usage;
  1370. #else
  1371. goto usage;
  1372. #endif
  1373. else {
  1374. // Retrieve the Cluster IP Address or "ALL"
  1375. if (_wcsicmp (argv[arg_index], L"all") == 0)
  1376. {
  1377. target_cl = CVY_ALL_CLUSTERS;
  1378. }
  1379. else
  1380. {
  1381. target_cl = WlbsResolve(argv [arg_index]);
  1382. if (target_cl == 0)
  1383. goto usage;
  1384. }
  1385. arg_index++;
  1386. }
  1387. }
  1388. else if (_wcsicmp(argv[arg_index], L"registry") == 0)
  1389. {
  1390. command = registry;
  1391. target_host = CVY_LOCAL_HOST;
  1392. arg_index++;
  1393. if (argc < 4) goto reg_usage;
  1394. if (_wcsicmp(argv[arg_index], L"mcastipaddress") == 0) {
  1395. arg_index++;
  1396. param1 = mcastipaddress;
  1397. if (!(param2 = WlbsResolve(argv[arg_index])))
  1398. goto reg_usage;
  1399. /* The multicast IP address should be in the range of (224-239).x.x.x, but NOT (224-239).0.0.x or (224-239).128.0.x. */
  1400. if ((param2 & 0xf0) != 0xe0 || (param2 & 0x00ffff00) == 0 || (param2 & 0x00ffff00) == 0x00008000) {
  1401. Message_print (IDS_CTR_REG_INVAL_MCASTIPADDRESS);
  1402. goto reg_usage;
  1403. }
  1404. } else if (_wcsicmp(argv[arg_index], L"iptomcastip") == 0) {
  1405. arg_index++;
  1406. param1 = iptomcastip;
  1407. if (_wcsicmp(argv[arg_index], L"on") == 0)
  1408. param2 = 1;
  1409. else if (_wcsicmp(argv[arg_index], L"off") == 0)
  1410. param2 = 0;
  1411. else
  1412. goto reg_usage;
  1413. } else if (_wcsicmp(argv[arg_index], L"masksrcmac") == 0) {
  1414. arg_index++;
  1415. param1 = masksrcmac;
  1416. if (_wcsicmp(argv[arg_index], L"on") == 0)
  1417. param2 = 1;
  1418. else if (_wcsicmp(argv[arg_index], L"off") == 0)
  1419. param2 = 0;
  1420. else
  1421. goto reg_usage;
  1422. } else if (_wcsicmp(argv[arg_index], L"iptomacenable") == 0) {
  1423. arg_index++;
  1424. param1 = iptomacenable;
  1425. if (_wcsicmp(argv[arg_index], L"on") == 0)
  1426. param2 = 1;
  1427. else if (_wcsicmp(argv[arg_index], L"off") == 0)
  1428. param2 = 0;
  1429. else
  1430. goto reg_usage;
  1431. } else {
  1432. Message_print(IDS_CTR_REG_KEY, argv[arg_index]);
  1433. goto reg_usage;
  1434. }
  1435. arg_index++;
  1436. if (arg_index == argc) {
  1437. target_cl = CVY_ALL_CLUSTERS;
  1438. } else if (arg_index + 1 < argc)
  1439. goto reg_usage;
  1440. else {
  1441. if (!(target_cl = WlbsResolve(argv[arg_index])))
  1442. goto reg_usage;
  1443. arg_index++;
  1444. }
  1445. if (argc != arg_index)
  1446. goto reg_usage;
  1447. }
  1448. else if (_wcsicmp(argv[arg_index], L"tracing") == 0)
  1449. {
  1450. TraceOutput output;
  1451. DWORD flags = TL_ERROR;
  1452. DWORD tracing = 0;
  1453. arg_index++;
  1454. if (argc < 3) goto trace_usage;
  1455. if (_wcsicmp(argv[arg_index], L"file") == 0)
  1456. output = TRACE_FILE;
  1457. else if (_wcsicmp(argv[arg_index], L"console") == 0)
  1458. output = TRACE_CONSOLE;
  1459. else if (_wcsicmp(argv[arg_index], L"debugger") == 0)
  1460. output = TRACE_DEBUGGER;
  1461. else if (_wcsicmp(argv[arg_index], L"on") == 0) {
  1462. output = TRACE_ALL;
  1463. arg_index--;
  1464. } else if (_wcsicmp(argv[arg_index], L"off") == 0) {
  1465. output = TRACE_ALL;
  1466. arg_index--;
  1467. } else
  1468. goto trace_usage;
  1469. arg_index++;
  1470. if (_wcsicmp(argv[arg_index], L"on") == 0)
  1471. tracing = 1;
  1472. else if (_wcsicmp(argv[arg_index], L"off") == 0)
  1473. tracing = 0;
  1474. else
  1475. goto trace_usage;
  1476. arg_index++;
  1477. if (tracing && !Parse_tracing(argc, argv, &arg_index, &flags))
  1478. goto trace_usage;
  1479. if (Process_tracing(tracing, output, flags) != ERROR_SUCCESS)
  1480. Message_print(IDS_CTR_TRACE_FAILED);
  1481. return CVY_OK;
  1482. }
  1483. else
  1484. goto usage;
  1485. /* The remote control parameters need to be parsed. */
  1486. dest_password = NULL;
  1487. dest_addr = 0;
  1488. dest_port = 0;
  1489. while (arg_index < argc) {
  1490. if (argv[arg_index][0] == L'/' || argv[arg_index][0] == L'-') {
  1491. if (_wcsicmp(argv[arg_index] + 1, L"PASSW") == 0) {
  1492. arg_index++;
  1493. if (arg_index >= argc || argv[arg_index][0] == L'/' || argv[arg_index][0] == L'-') {
  1494. HANDLE hConsole;
  1495. DWORD dwMode; // console mode
  1496. DWORD dwInputMode; // stdin input mode
  1497. Message_print(IDS_CTR_PASSW);
  1498. hConsole = GetStdHandle(STD_INPUT_HANDLE);
  1499. dwInputMode = GetFileType(hConsole);
  1500. //
  1501. // prompt for password, making sure password isn't echoed
  1502. // if the stdin is redirected, don't bother querying/changing console mode
  1503. //
  1504. if (dwInputMode == FILE_TYPE_CHAR) {
  1505. if (!GetConsoleMode(hConsole, &dwMode)) {
  1506. Error_print(FALSE);
  1507. return CVY_ERROR_SYSTEM;
  1508. }
  1509. if (!SetConsoleMode(hConsole, dwMode &= ~ENABLE_ECHO_INPUT)) {
  1510. Error_print(FALSE);
  1511. return CVY_ERROR_SYSTEM;
  1512. }
  1513. }
  1514. for (i = 0; i < CVY_STR_SIZE; i++) {
  1515. //
  1516. // read a character, copying to the buffer
  1517. // break out of loop on CR and EOF
  1518. //
  1519. if ((psw_buf[i] = fgetwc(stdin)) == WEOF)
  1520. break;
  1521. if (psw_buf[i] == L'\n')
  1522. break;
  1523. }
  1524. // NULL terminate the password
  1525. psw_buf[i] = L'\0';
  1526. // restore previous console mode
  1527. if (dwInputMode == FILE_TYPE_CHAR)
  1528. SetConsoleMode(hConsole, dwMode);
  1529. WConsole(L"\n");
  1530. if (i == 0)
  1531. dest_password = NULL;
  1532. else
  1533. dest_password = psw_buf;
  1534. } else {
  1535. dest_password = argv[arg_index];
  1536. arg_index ++;
  1537. }
  1538. } else if (_wcsicmp(argv[arg_index] + 1, L"PORT") == 0) {
  1539. arg_index++;
  1540. if (arg_index >= argc || argv[arg_index][0] == L'/' || argv[arg_index][0] == L'-')
  1541. goto usage;
  1542. dest_port = (USHORT)_wtoi(argv[arg_index]);
  1543. if (dest_port == 0)
  1544. goto usage;
  1545. arg_index++;
  1546. } else if (_wcsicmp(argv[arg_index] + 1, L"DEST") == 0) {
  1547. arg_index++;
  1548. if (arg_index >= argc || argv[arg_index][0] == L'/' || argv[arg_index][0] == L'-')
  1549. goto usage;
  1550. dest_addr = WlbsResolve(argv [arg_index]);
  1551. if (dest_addr == 0)
  1552. goto usage;
  1553. arg_index++;
  1554. } else
  1555. goto usage;
  1556. } else
  1557. goto usage;
  1558. }
  1559. if (target_cl != CVY_ALL_CLUSTERS) {
  1560. Process(command, target_cl, target_host, param1, param2, dest_port, dest_addr, dest_password);
  1561. return CVY_OK;
  1562. }
  1563. /* Enumerate all the clusters and call process for each one of them */
  1564. else {
  1565. DWORD clusters[CVY_MAX_ADAPTERS];
  1566. DWORD i, len;
  1567. len = CVY_MAX_ADAPTERS;
  1568. WlbsEnumClusters(clusters, &len);
  1569. if (!len) {
  1570. Message_print(IDS_CTR_NO_CVY, CVY_NAME);
  1571. return CVY_OK;
  1572. }
  1573. for (i = 0 ; i < len; i++) {
  1574. WCHAR wbuf[CVY_STR_SIZE];
  1575. DWORD buflen = CVY_STR_SIZE;
  1576. WlbsAddressToString(clusters[i], wbuf, &buflen);
  1577. Message_print(IDS_CTR_CLUSTER_ID, wbuf);
  1578. Process(command, clusters[i], target_host, param1, param2, dest_port, dest_addr, dest_password);
  1579. if (i < len - 1)
  1580. WConsole (L"\n");
  1581. }
  1582. return CVY_OK;
  1583. }
  1584. reg_usage:
  1585. Message_print(IDS_CTR_REG_USAGE, CVY_NAME);
  1586. return CVY_ERROR_USAGE;
  1587. trace_usage:
  1588. Message_print(IDS_CTR_TRACE_USAGE, CVY_NAME);
  1589. return CVY_ERROR_USAGE;
  1590. }
  1591. }