/*++ Copyright(c) 1998,99 Microsoft Corporation Module Name: control.cpp Abstract: Windows Load Balancing Service (WLBS) Command-line utility Author: kyrilf ramkrish (Post Win2K) --*/ #include #include #include #include #include #include #include #include #include #include #include #define WLBSAPI_INTERNAL_ONLY #define BACKWARD_COMPATIBILITY #define CVY_MAX_ADAPTERS 16 #include "wlbsutil.h" #include "wlbsctrl.h" #include "wlbsconfig.h" #include "wlbsparm.h" #include "wlbsiocl.h" #define CLIENT #include "log_msgs.h" /* CONSTANTS */ #define CVY_OK 1 #define CVY_ERROR_USAGE -1 #define CVY_ERROR_REGISTRY -2 #define CVY_ERROR_SYSTEM -3 #define CVY_ERROR_USER -4 #define CVY_BUF_SIZE 4096 #define CVY_MAX_EVENTS 10 #define CVY_MAX_INSERTS 10 #define CVY_ALL_CLUSTERS 0xffffffff #define CVY_ALL_HOSTS 0xffffffff #define CVY_LOCAL_CLUSTER 0 #define CVY_LOCAL_HOST WLBS_LOCAL_HOST #define TL_ERROR ((DWORD)0x00010000) #define TL_WARN ((DWORD)0x00020000) #define TL_INFO ((DWORD)0x00040000) typedef enum { mcastipaddress, iptomcastip, masksrcmac, iptomacenable } WLBS_REG_KEYS; typedef enum { query, suspend, resume, __start, stop, drainstop, enable, disable, drain, reload, display, ip2mac, help, registry, invalid } WLBS_COMMANDS; typedef enum { TRACE_ALL, TRACE_FILE, TRACE_CONSOLE, TRACE_DEBUGGER } TraceOutput; static HANDLE file_hdl = NULL; static HANDLE ConsoleHdl; static BYTE buffer [CVY_BUF_SIZE]; static WCHAR message [CVY_BUF_SIZE]; static WCHAR ConsoleBuf [CVY_BUF_SIZE]; static WCHAR wbuf [CVY_STR_SIZE]; static WCHAR psw_buf [CVY_STR_SIZE]; VOID WConsole(const wchar_t *fmt, ...) { va_list arglist; DWORD res1, res2; DWORD TotalLen; // Form a string out of the arguments va_start(arglist, fmt); wvnsprintf(ConsoleBuf, CVY_BUF_SIZE, fmt, arglist); va_end(arglist); // Attempt WriteConsole, if it fails, do a wprintf TotalLen = lstrlenW(ConsoleBuf); if (!WriteConsole(ConsoleHdl, ConsoleBuf, lstrlenW(ConsoleBuf), &res1, &res2)) { wprintf(ConsoleBuf); } return; } VOID Message_print (DWORD id, ...) { va_list arglist; DWORD error; va_start(arglist, id); if (FormatMessage(FORMAT_MESSAGE_FROM_HMODULE, NULL, id, 0, message, CVY_BUF_SIZE, & arglist) == 0) { error = GetLastError(); // // Can't localize this because we've got a failure trying // to display a localized message.. // WConsole(L"Could not print error message due to: "); if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, message, CVY_BUF_SIZE, NULL) == 0) WConsole(L"%d\n", error); else WConsole(L"\n %ls\n", message); } else WConsole(L"%ls", message); } VOID Error_print (BOOL sock) { DWORD error; if (sock) { error = WSAGetLastError(); switch (error) { case WSAENETUNREACH: Message_print(IDS_CTR_WS_NUNREACH); break; case WSAETIMEDOUT: Message_print(IDS_CTR_WS_TIMEOUT); break; case WSAHOST_NOT_FOUND: Message_print(IDS_CTR_WS_NOAUTH); break; case WSATRY_AGAIN: Message_print(IDS_CTR_WS_NODNS); break; case WSAENETDOWN: Message_print(IDS_CTR_WS_NETFAIL); break; case WSAEHOSTUNREACH: Message_print(IDS_CTR_WS_HUNREACH); break; case WSAENETRESET: Message_print(IDS_CTR_WS_RESET); break; default: Message_print(IDS_CTR_ER_CODE, error); break; } } else { error = GetLastError(); if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, message, CVY_BUF_SIZE, NULL) == 0) Message_print(IDS_CTR_ER_CODE, error); else WConsole(L"%ls\n", message); } } INT Report (WLBS_COMMANDS command, BOOLEAN condensed, ULONG ret_code, ULONG param1, ULONG param2, ULONG query_state, ULONG host_id, ULONG host_map) { ULONG i; BOOL first; switch (command) { case reload: if (ret_code == WLBS_BAD_PARAMS) { Message_print(IDS_CTR_BAD_PARAMS); return CVY_ERROR_USER; } else Message_print(IDS_CTR_RELOADED); break; case resume: if (condensed) if (ret_code == WLBS_ALREADY) Message_print(IDS_CTR_RESUMED_C_A); else Message_print(IDS_CTR_RESUMED_C); else if (ret_code == WLBS_ALREADY) Message_print(IDS_CTR_RESUMED_A); else Message_print(IDS_CTR_RESUMED); break; case suspend: if (condensed) if (ret_code == WLBS_ALREADY) Message_print(IDS_CTR_SUSPENDED_C_A); else { if (ret_code == WLBS_STOPPED) Message_print(IDS_CTR_FROM_START_C); Message_print(IDS_CTR_SUSPENDED_C); } else if (ret_code == WLBS_ALREADY) Message_print(IDS_CTR_SUSPENDED_A); else { if (ret_code == WLBS_STOPPED) Message_print(IDS_CTR_FROM_START); Message_print(IDS_CTR_SUSPENDED); } break; case __start: if (ret_code == WLBS_SUSPENDED) { if (condensed) Message_print(IDS_CTR_SUSPENDED_C); else Message_print(IDS_CTR_SUSPENDED); return CVY_ERROR_USER; } else if (ret_code == WLBS_BAD_PARAMS) { if (condensed) Message_print(IDS_CTR_BAD_PARAMS_C); else Message_print(IDS_CTR_BAD_PARAMS); return CVY_ERROR_USER; } else { if (condensed) if (ret_code == WLBS_ALREADY) Message_print(IDS_CTR_STARTED_C_A); else { if (ret_code == WLBS_DRAIN_STOP) Message_print(IDS_CTR_FROM_DRAIN_C); Message_print(IDS_CTR_STARTED_C); } else if (ret_code == WLBS_ALREADY) Message_print(IDS_CTR_STARTED_A); else { if (ret_code == WLBS_DRAIN_STOP) Message_print(IDS_CTR_FROM_DRAIN); Message_print(IDS_CTR_STARTED); } } break; case stop: if (ret_code == WLBS_SUSPENDED) { if (condensed) Message_print(IDS_CTR_SUSPENDED_C); else Message_print(IDS_CTR_SUSPENDED); return CVY_ERROR_USER; }else { if (condensed) if (ret_code == WLBS_ALREADY) Message_print(IDS_CTR_STOPPED_C_A); else Message_print(IDS_CTR_STOPPED_C); else if (ret_code == WLBS_ALREADY) Message_print(IDS_CTR_STOPPED_A); else Message_print(IDS_CTR_STOPPED); } break; case drainstop: if (ret_code == WLBS_SUSPENDED) { if (condensed) Message_print(IDS_CTR_SUSPENDED_C); else Message_print(IDS_CTR_SUSPENDED); return CVY_ERROR_USER; } else { if (condensed) if (ret_code == WLBS_STOPPED) Message_print(IDS_CTR_STOPPED_C); else if (ret_code == WLBS_ALREADY) Message_print(IDS_CTR_DRAINED_C_A); else Message_print(IDS_CTR_DRAINED_C); else if (ret_code == WLBS_STOPPED) Message_print(IDS_CTR_STOPPED); else if (ret_code == WLBS_ALREADY) Message_print(IDS_CTR_DRAINED_A); else Message_print(IDS_CTR_DRAINED); } break; case enable: case disable: case drain: if (ret_code == WLBS_SUSPENDED) { if (condensed) Message_print(IDS_CTR_SUSPENDED_C); else Message_print(IDS_CTR_SUSPENDED); return CVY_ERROR_USER; } else if (ret_code == WLBS_STOPPED) { if (condensed) Message_print(IDS_CTR_RLS_ST_C); else Message_print(IDS_CTR_RLS_ST); return CVY_ERROR_USER; } else if (ret_code == WLBS_NOT_FOUND) { if (param2 == IOCTL_ALL_PORTS) { if (param1 == IOCTL_ALL_VIPS) { if (condensed) Message_print(IDS_CTR_RLS_NORULES_C); else Message_print(IDS_CTR_RLS_NORULES); } else if (param1 == IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP)) { if (condensed) Message_print(IDS_CTR_RLS_NO_ALL_VIP_RULES_C); else Message_print(IDS_CTR_RLS_NO_ALL_VIP_RULES); } else { WCHAR szIpAddress[WLBS_MAX_CL_IP_ADDR+1]; AbcdWszFromIpAddress(param1, szIpAddress); if (condensed) Message_print(IDS_CTR_RLS_NO_SPECIFIC_VIP_RULES_C, szIpAddress); else Message_print(IDS_CTR_RLS_NO_SPECIFIC_VIP_RULES, szIpAddress); } } else { if (param1 == IOCTL_ALL_VIPS) { if (condensed) Message_print(IDS_CTR_RLS_NONE_C, param2); else Message_print(IDS_CTR_RLS_NONE, param2); } else if (param1 == IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP)) { if (condensed) Message_print(IDS_CTR_RLS_NO_ALL_VIP_RULE_FOR_PORT_C, param2); else Message_print(IDS_CTR_RLS_NO_ALL_VIP_RULE_FOR_PORT, param2); } else { WCHAR szIpAddress[WLBS_MAX_CL_IP_ADDR+1]; AbcdWszFromIpAddress(param1, szIpAddress); if (condensed) Message_print(IDS_CTR_RLS_NO_SPECIFIC_VIP_RULE_FOR_PORT_C, szIpAddress, param2); else Message_print(IDS_CTR_RLS_NO_SPECIFIC_VIP_RULE_FOR_PORT, szIpAddress, param2); } } return CVY_ERROR_USER; } else { switch (command) { case enable: if (condensed) if (ret_code == WLBS_ALREADY) Message_print(IDS_CTR_RLS_EN_C_A); else Message_print(IDS_CTR_RLS_EN_C); else if (ret_code == WLBS_ALREADY) Message_print(IDS_CTR_RLS_EN_A); else Message_print(IDS_CTR_RLS_EN); break; case disable: if (condensed) if (ret_code == WLBS_ALREADY) Message_print(IDS_CTR_RLS_DS_C_A); else Message_print(IDS_CTR_RLS_DS_C); else if (ret_code == WLBS_ALREADY) Message_print(IDS_CTR_RLS_DS_A); else Message_print(IDS_CTR_RLS_DS); break; case drain : if (condensed) if (ret_code == WLBS_ALREADY) Message_print(IDS_CTR_RLS_DR_C_A); else Message_print(IDS_CTR_RLS_DR_C); else if (ret_code == WLBS_ALREADY) Message_print(IDS_CTR_RLS_DR_A); else Message_print(IDS_CTR_RLS_DR); break; } } break; case query: switch (query_state) { case WLBS_SUSPENDED: if (condensed) Message_print(IDS_CTR_CVG_SP_C); else Message_print(IDS_CTR_CVG_SP, host_id); return CVY_OK; case WLBS_STOPPED: if (condensed) Message_print(IDS_CTR_CVG_UN_C); else Message_print(IDS_CTR_CVG_UN, host_id); return CVY_OK; case WLBS_DISCONNECTED: if (condensed) Message_print(IDS_CTR_MEDIA_DISC_C); else Message_print(IDS_CTR_MEDIA_DISC, host_id); return CVY_OK; case WLBS_DRAINING: if (condensed) Message_print(IDS_CTR_CVG_DR_C); else Message_print(IDS_CTR_CVG_DR, host_id); break; case WLBS_CONVERGING: if (condensed) Message_print(IDS_CTR_CVG_PR_C); else Message_print(IDS_CTR_CVG_PR, host_id); break; case WLBS_CONVERGED: if (condensed) Message_print(IDS_CTR_CVG_SL_C); else Message_print(IDS_CTR_CVG_SL, host_id); break; case WLBS_DEFAULT: if (condensed) Message_print(IDS_CTR_CVG_MS_C); else Message_print(IDS_CTR_CVG_MS, host_id); break; default: if (condensed) Message_print(IDS_CTR_CVG_ER_C); else Message_print(IDS_CTR_CVG_ER, query_state); return CVY_ERROR_SYSTEM; } if (!condensed) { first = TRUE; for (i = 0; i < 32; i ++) { if (host_map & (1 << i)) { if (!first) WConsole (L", "); else first = FALSE; WConsole(L"%d", i + 1); } } WConsole (L"\n"); } break; default: Message_print(IDS_CTR_IO_ER, command); break; } return CVY_OK; } INT Display (DWORD cluster) { HANDLE hdl; HINSTANCE lib; DWORD flag; EVENTLOGRECORD * recp = (EVENTLOGRECORD *)buffer; DWORD actual, needed, records, index = 0, got = 0; DWORD j, i, code; PWCHAR strp; PWCHAR prot; WCHAR aff; time_t curr_time; PWLBS_PORT_RULE rp, rulep; BYTE * inserts[CVY_MAX_INSERTS]; WLBS_REG_PARAMS params; DWORD status; status = WlbsReadReg(cluster, ¶ms); if (status != WLBS_OK) { Message_print (IDS_CTR_REMOTE); return CVY_ERROR_USER; } Message_print(IDS_CTR_DSP_CONFIGURATION); time (& curr_time); WConsole(L"%-25.25ls = %ls", L"Current time", _wctime (& curr_time)); WConsole(L"%-25.25ls = %d\n", CVY_NAME_VERSION, params.i_parms_ver); WConsole(L"%-25.25ls = %ls\n", CVY_NAME_VIRTUAL_NIC, params.i_virtual_nic_name); WConsole(L"%-25.25ls = %d\n", CVY_NAME_ALIVE_PERIOD, params.alive_period); WConsole(L"%-25.25ls = %d\n", CVY_NAME_ALIVE_TOLER, params.alive_tolerance); WConsole(L"%-25.25ls = %d\n", CVY_NAME_NUM_ACTIONS, params.num_actions); WConsole(L"%-25.25ls = %d\n", CVY_NAME_NUM_PACKETS, params.num_packets); WConsole(L"%-25.25ls = %d\n", CVY_NAME_NUM_SEND_MSGS, params.num_send_msgs); WConsole(L"%-25.25ls = %ls\n", CVY_NAME_NETWORK_ADDR, params.cl_mac_addr); WConsole(L"%-25.25ls = %ls\n", CVY_NAME_DOMAIN_NAME, params.domain_name); WConsole(L"%-25.25ls = %ls\n", CVY_NAME_CL_IP_ADDR, params.cl_ip_addr); WConsole(L"%-25.25ls = %ls\n", CVY_NAME_CL_NET_MASK, params.cl_net_mask); WConsole(L"%-25.25ls = %ls\n", CVY_NAME_DED_IP_ADDR, params.ded_ip_addr); WConsole(L"%-25.25ls = %ls\n", CVY_NAME_DED_NET_MASK, params.ded_net_mask); WConsole(L"%-25.25ls = %d\n", CVY_NAME_HOST_PRIORITY, params.host_priority); WConsole(L"%-25.25ls = %ls\n", CVY_NAME_CLUSTER_MODE, params.cluster_mode ? L"ENABLED" : L"DISABLED"); WConsole(L"%-25.25ls = %d\n", CVY_NAME_DSCR_PER_ALLOC, params.dscr_per_alloc); WConsole(L"%-25.25ls = %d\n", CVY_NAME_MAX_DSCR_ALLOCS, params.max_dscr_allocs); WConsole(L"%-25.25ls = %d\n", CVY_NAME_SCALE_CLIENT, params.i_scale_client); WConsole(L"%-25.25ls = %d\n", CVY_NAME_NBT_SUPPORT, params.i_nbt_support); WConsole(L"%-25.25ls = %d\n", CVY_NAME_MCAST_SUPPORT, params.mcast_support); WConsole(L"%-25.25ls = %d\n", CVY_NAME_MCAST_SPOOF, params.i_mcast_spoof); WConsole(L"%-25.25ls = %d\n", CVY_NAME_MASK_SRC_MAC, params.mask_src_mac); WConsole(L"%-25.25ls = %ls\n", CVY_NAME_IGMP_SUPPORT, params.fIGMPSupport ? L"ENABLED" : L"DISABLED"); WConsole(L"%-25.25ls = %ls\n", CVY_NAME_IP_TO_MCASTIP, params.fIpToMCastIp ? L"ENABLED" : L"DISABLED"); WConsole(L"%-25.25ls = %ls\n", CVY_NAME_MCAST_IP_ADDR, params.szMCastIpAddress); WConsole(L"%-25.25ls = %d\n", CVY_NAME_NETMON_ALIVE, params.i_netmon_alive); if (params.i_effective_version == CVY_NT40_VERSION_FULL) WConsole(L"%-25.25ls = %ls\n", CVY_NAME_EFFECTIVE_VERSION, CVY_NT40_VERSION); else WConsole(L"%-25.25ls = %ls\n", CVY_NAME_EFFECTIVE_VERSION, CVY_VERSION); WConsole(L"%-25.25ls = %d\n", CVY_NAME_IP_CHG_DELAY, params.i_ip_chg_delay); WConsole(L"%-25.25ls = %d\n", CVY_NAME_CONVERT_MAC, params.i_convert_mac); WConsole(L"%-25.25ls = %d\n", CVY_NAME_CLEANUP_DELAY, params.i_cleanup_delay); WConsole(L"%-25.25ls = %d\n", CVY_NAME_RCT_ENABLED, params.rct_enabled); WConsole(L"%-25.25ls = %d\n", CVY_NAME_RCT_PORT, params.rct_port); WConsole(L"%-25.25ls = 0x%X\n", CVY_NAME_RCT_PASSWORD, params.i_rct_password); WConsole(L"%-25.25ls = 0x%X\n", CVY_NAME_RMT_PASSWORD, params.i_rmt_password); WConsole(L"%-25.25ls = %ls\n", CVY_NAME_CUR_VERSION, CVY_VERSION); WConsole(L"%-25.25ls = 0x%X\n", CVY_NAME_INSTALL_DATE, params.install_date); WConsole(L"%-25.25ls = 0x%X\n", CVY_NAME_VERIFY_DATE, params.i_verify_date); WConsole(L"%-25.25ls = %d\n", CVY_NAME_NUM_RULES, params.i_num_rules); WConsole(L"%-25.25ls = %ls\n", CVY_NAME_BDA_TEAMING, params.bda_teaming.active ? L"ENABLED" : L"DISABLED"); WConsole(L"%-25.25ls = %ls\n", CVY_NAME_BDA_TEAM_ID, params.bda_teaming.team_id); WConsole(L"%-25.25ls = %ls\n", CVY_NAME_BDA_MASTER, params.bda_teaming.master ? L"ENABLED" : L"DISABLED"); WConsole(L"%-25.25ls = %ls\n", CVY_NAME_BDA_REVERSE_HASH, params.bda_teaming.reverse_hash ? L"ENABLED" : L"DISABLED"); WConsole(L"%-25.25ls \n", CVY_NAME_PORT_RULES); WConsole(L"Virtual IP addr Start\tEnd\tProt\tMode\t\tPri\tLoad\tAffinity\n"); for (i = 0; i < params.i_num_rules; i ++) { rp = params.i_port_rules + i; code = CVY_RULE_CODE_GET(rp); CVY_RULE_CODE_SET(rp); if (code != CVY_RULE_CODE_GET(rp)) { WConsole(L"bad rule code 0x%08x vs 0x%08x\n", code, CVY_RULE_CODE_GET(rp)); rp->code = code; continue; } if (!rp->valid) { WConsole(L"rule is not valid\n"); continue; } if (rp->start_port > rp->end_port) { WConsole(L"bad port range %d-%d\n", rp->start_port, rp->end_port); continue; } for (j = 0; j < i; j ++) { rulep = params.i_port_rules + j; if ((IpAddressFromAbcdWsz(rulep->virtual_ip_addr) == IpAddressFromAbcdWsz(rp->virtual_ip_addr)) && ((rulep->start_port < rp->start_port && rulep->end_port >= rp->start_port) || (rulep->start_port >= rp->start_port && rulep->start_port <= rp->end_port))) { 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); continue; } } if (rp->start_port > CVY_MAX_PORT) { WConsole(L"bad start port %d\n", rp->start_port); continue; } if (rp->end_port > CVY_MAX_PORT) { WConsole(L"bad end port %d\n", rp->end_port); continue; } if (rp->protocol < CVY_MIN_PROTOCOL || rp->protocol > CVY_MAX_PROTOCOL) { WConsole(L"bad protocol %d\n", rp->protocol); continue; } if (rp->mode < CVY_MIN_MODE || rp->mode > CVY_MAX_MODE) { WConsole(L"bad mode %d\n", rp->mode); continue; } switch (rp->protocol) { case CVY_TCP: prot = L"TCP"; break; case CVY_UDP: prot = L"UDP"; break; default: prot = L"Both"; break; } if (!lstrcmpi(rp->virtual_ip_addr, CVY_DEF_ALL_VIP)) WConsole(L"%15ls\t%5d\t%5d\t%ls\t", L"ALL", rp->start_port, rp->end_port, prot); else WConsole(L"%15ls\t%5d\t%5d\t%ls\t", rp->virtual_ip_addr, rp->start_port, rp->end_port, prot); switch (rp->mode) { case CVY_SINGLE: WConsole(L"%-10.10ls\t%2d", L"Single", rp->mode_data.single.priority); break; case CVY_MULTI: if (rp->mode_data.multi.affinity == CVY_AFFINITY_NONE) aff = L'N'; else if (rp->mode_data.multi.affinity == CVY_AFFINITY_SINGLE) aff = L'S'; else aff = L'C'; if (rp->mode_data.multi.equal_load) WConsole(L"%-10.10ls\t\tEqual\t%lc", L"Multiple", aff); else { if (rp->mode_data.multi.load > CVY_MAX_LOAD) { WConsole(L"bad load %d\n", rp->mode_data.multi.load); continue; } WConsole(L"%-10.10ls\t\t%3d\t%lc", L"Multiple", rp->mode_data.multi.load, aff); } break; default: WConsole(L"%-10.10ls", L"Disabled"); break; } WConsole(L"\n"); } WConsole(L"\n"); Message_print(IDS_CTR_DSP_EVENTLOG); hdl = OpenEventLog (NULL, L"System"); if (hdl == NULL) { WConsole(L"Could not open event log due to:\n"); Error_print (FALSE); return CVY_ERROR_SYSTEM; } if (!GetNumberOfEventLogRecords(hdl, &records)) { WConsole(L"Could not get number of records in event log due to:\n"); Error_print (FALSE); CloseEventLog (hdl); return CVY_ERROR_SYSTEM; } if (!GetOldestEventLogRecord (hdl, & index)) { WConsole(L"Could not get the index of the latest event log record due to:\n"); Error_print (FALSE); CloseEventLog (hdl); return CVY_ERROR_SYSTEM; } swprintf(message + GetSystemDirectory (message, CVY_BUF_SIZE), L"\\drivers\\%ls.sys", CVY_NAME); lib = LoadLibrary(message); if (lib == NULL) { WConsole(L"Could not load driver image file due to:\n"); Error_print (FALSE); CloseEventLog (hdl); return CVY_ERROR_SYSTEM; } index += records - 1; flag = EVENTLOG_SEEK_READ | EVENTLOG_BACKWARDS_READ; while (got < CVY_MAX_EVENTS && ReadEventLog(hdl, flag, index, recp, CVY_BUF_SIZE, &actual, &needed)) { while (got < CVY_MAX_EVENTS && actual > 0) { if (wcscmp ((PWSTR)(((PBYTE) recp) + sizeof(EVENTLOGRECORD)), CVY_NAME) == 0) { WConsole(L"#%02d ID: 0x%08X Type: %d Category: %d ", index--, recp->EventID, recp->EventType, recp->EventCategory); time_t TimeGenerated = recp->TimeGenerated; WConsole(L"Time: %ls", _wctime(&TimeGenerated)); strp = (PWCHAR)((LPBYTE)recp + recp->StringOffset); for (i = 0; i < CVY_MAX_INSERTS; i ++) { if (i < recp->NumStrings) { inserts[i] = (BYTE*)strp; strp += wcslen (strp) + 1; } else inserts[i] = 0; } if (FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ARGUMENT_ARRAY, lib, recp->EventID, 0, (PWCHAR)message, CVY_BUF_SIZE, (va_list *)inserts) == 0) { WConsole(L"Could not load message string due to:\n"); Error_print(FALSE); } else WConsole(L"%ls", message); for (i = 0; i < recp->DataLength / sizeof(DWORD); i ++) { if (i != 0 && i % 8 == 0) WConsole(L"\n"); WConsole(L"%08X ", *(UNALIGNED DWORD*)((PBYTE)recp + recp->DataOffset + i * sizeof(DWORD))); } WConsole(L"\n\n"); got++; } actual -= recp->Length; recp = (EVENTLOGRECORD *)((LPBYTE)recp + recp->Length); index--; } recp = (EVENTLOGRECORD *)buffer; flag = EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ; } FreeLibrary(lib); CloseEventLog(hdl); Message_print(IDS_CTR_DSP_IPCONFIG); fflush(stdout); _wsystem(L"ipconfig /all"); Message_print(IDS_CTR_DSP_STATE); return CVY_OK; } /* This function parses the remaining arguments to determine whether the command * is for all clusters, or a remote cluster or for a single local cluster. */ BOOLEAN Parse (INT argc, PWCHAR argv [], PINT arg_index, PDWORD ptarget_cl, PDWORD ptarget_host) { PWCHAR phost; #ifdef BACKWARD_COMPATIBILITY *ptarget_cl = CVY_ALL_CLUSTERS; *ptarget_host = CVY_LOCAL_HOST; if (*arg_index >= argc) return TRUE; #endif /* At this point, argv[arg_index] == cluster_ip and/or argv[arg_index+1] == /local or /passw or /port */ // // Special check for /PASSW without a cluster ID, because this is // a common error // if ( _wcsicmp (argv [*arg_index], L"/passw") == 0 || _wcsicmp (argv [*arg_index], L"-passw") == 0) { Message_print (IDS_CTR_PSSW_WITHOUT_CLUSTER); return FALSE; } phost = wcschr(argv[* arg_index], L':'); /* if there is no host part - operation applies to all hosts */ if (phost == NULL) { *ptarget_host = CVY_ALL_HOSTS; } else { /* split target name so targ points to cluster name and host to host name */ *phost = 0; phost ++; if (wcslen(phost) <= 2 && phost[0] >= L'0' && phost[0] <= L'9' && ((phost[1] >= L'0' && phost[1] <= L'9') || phost[1] == 0)) *ptarget_host = _wtoi(phost); else { *ptarget_host = WlbsResolve(phost); if (*ptarget_host == 0) { Message_print(IDS_CTR_BAD_HOST_NAME_IP); return FALSE; } } } // Retrieve the Cluster IP Address or "ALL" if (_wcsicmp (argv[*arg_index], L"all") == 0) { // If there is a host part, then, cluster ip can not be "ALL" if (*ptarget_host != CVY_ALL_HOSTS) { Message_print(IDS_CTR_BAD_CLUSTER_NAME_IP); return FALSE; } *ptarget_cl = CVY_ALL_CLUSTERS; } else { *ptarget_cl = WlbsResolve(argv[*arg_index]); if (*ptarget_cl == 0) { Message_print(IDS_CTR_BAD_CLUSTER_NAME_IP); return FALSE; } } (*arg_index)++; // If there is no host part, then, there better be the LOCAL or GLOBAL flag if (*ptarget_host == CVY_ALL_HOSTS) { if (*arg_index == argc) { #ifdef BACKWARD_COMPATIBILITY return TRUE; #else Message_print(IDS_CTR_CLUSTER_WITHOUT_LOCAL_GLOBAL_FLAG); return FALSE; #endif } if (_wcsicmp (argv[*arg_index], L"local") == 0) { *ptarget_host = CVY_LOCAL_HOST; (*arg_index)++; } #ifdef BACKWARD_COMPATIBILITY else if ((argv[*arg_index][0] == L'/') || (argv[*arg_index][0] == L'-')) { if (_wcsicmp(argv[*arg_index] + 1, L"local") == 0) { *ptarget_host = CVY_LOCAL_HOST; (*arg_index)++; } } #endif else if (_wcsicmp (argv[*arg_index], L"global") == 0) { // Already set to CVY_ALL_HOSTS (*arg_index)++; } else { Message_print(IDS_CTR_CLUSTER_WITHOUT_LOCAL_GLOBAL_FLAG); return FALSE; } } if (*arg_index == argc) return TRUE; if ((argv[*arg_index][0] == L'/') || (argv[*arg_index][0] == L'-')) { #ifdef BACKWARD_COMPATIBILITY if (_wcsicmp(argv[*arg_index] + 1, L"local") == 0) { (*arg_index)++; *ptarget_host = CVY_LOCAL_HOST; return TRUE; } else #endif if ((_wcsicmp(argv[*arg_index] + 1, L"port") == 0) || (_wcsicmp(argv[*arg_index] + 1, L"passw") == 0)) return TRUE; else return FALSE; } else return FALSE; } VOID Process (WLBS_COMMANDS command, DWORD target_cl, DWORD target_host, ULONG param1, ULONG param2, ULONG dest_port, DWORD dest_addr, PWCHAR dest_password) { DWORD num_hosts = WLBS_MAX_HOSTS; DWORD len = WLBS_MAX_CL_IP_ADDR + 1; DWORD host_map; WLBS_RESPONSE response[WLBS_MAX_HOSTS]; DWORD status; DWORD i; WLBS_REG_PARAMS reg_data; WlbsPasswordSet(target_cl, dest_password); WlbsPortSet(target_cl, (USHORT)dest_port); switch (command) { case query: status = WlbsQuery(target_cl, target_host, response, &num_hosts, &host_map, NULL); break; case __start: status = WlbsStart(target_cl, target_host, response, &num_hosts); break; case stop: status = WlbsStop(target_cl, target_host, response, &num_hosts); break; case suspend: status = WlbsSuspend(target_cl, target_host, response, &num_hosts); break; case resume: status = WlbsResume(target_cl, target_host, response, &num_hosts); break; case drainstop: status = WlbsDrainStop(target_cl, target_host, response, &num_hosts); break; case enable: status = WlbsEnable(target_cl, target_host, response, &num_hosts, param1, param2); break; case disable: status = WlbsDisable(target_cl, target_host, response, &num_hosts, param1, param2); break; case drain: status = WlbsDrain(target_cl, target_host, response, &num_hosts, param1, param2); break; case reload: status = WlbsNotifyConfigChange(target_cl); if (status == WLBS_LOCAL_ONLY) { Message_print(IDS_CTR_REMOTE); return; } if (status == WLBS_REG_ERROR || status == WLBS_BAD_PARAMS) { Message_print(IDS_CTR_BAD_PARAMS); return; } if (status == WLBS_OK) { Message_print(IDS_CTR_RELOADED); return; } break; case display: Display(target_cl); Process(query, target_cl, target_host, param1, param2, dest_port, dest_addr, dest_password); return; case registry: if ((status = WlbsReadReg(target_cl, ®_data)) != WLBS_OK) { Message_print(IDS_CTR_REG_READ); return; } switch (param1) { case mcastipaddress: reg_data.fIpToMCastIp = FALSE; WlbsAddressToString(param2, reg_data.szMCastIpAddress, &len); break; case iptomcastip: reg_data.fIpToMCastIp = param2; break; case iptomacenable: reg_data.i_convert_mac = param2; break; case masksrcmac: reg_data.mask_src_mac = param2; break; } if ((status = WlbsWriteReg(target_cl, ®_data)) != WLBS_OK) { Message_print(IDS_CTR_REG_WRITE); return; } switch (param1) { case mcastipaddress: { TCHAR igmpaddr[WLBS_MAX_CL_IP_ADDR + 1]; DWORD len = WLBS_MAX_CL_IP_ADDR + 1; WlbsAddressToString (param2, igmpaddr, &len); Message_print(IDS_CTR_REG_MCASTIPADDRESS, igmpaddr); break; } case iptomcastip: Message_print((param2) ? IDS_CTR_REG_IPTOMCASTIP_ON : IDS_CTR_REG_IPTOMCASTIP_OFF); break; case masksrcmac: Message_print((param2) ? IDS_CTR_REG_MASKSRCMAC_ON : IDS_CTR_REG_MASKSRCMAC_OFF); break; case iptomacenable: Message_print((param2) ? IDS_CTR_REG_IPTOMACENABLE_ON : IDS_CTR_REG_IPTOMACENABLE_OFF); break; } return; default: return; } if (status == WLBS_INIT_ERROR) { Message_print(IDS_CTR_INIT); return; } if (status == WLBS_LOCAL_ONLY) { Message_print(IDS_CTR_WSOCK); return; } if (status == WLBS_REMOTE_ONLY) { Message_print(IDS_CTR_NO_CVY, CVY_NAME); return; } if (status >= WSABASEERR) { Message_print(IDS_CTR_WSOCK); Error_print(TRUE); return; } if (status == WLBS_TIMEOUT) { Message_print(IDS_CTR_NO_RSP3); if (command != query) Message_print(IDS_CTR_NO_RSP4, CVY_NAME); return; } if (target_host == CVY_LOCAL_HOST) { Report(command, FALSE, status, param1, param2, response[0].status, response[0].id, host_map); return; } /* Call Report for each host's response */ for (i = 0; i < num_hosts; i++) { if (response[i].address == 0) Message_print(IDS_CTR_HOST_NO_DED, response [i] . id); else { DWORD len = CVY_STR_SIZE; #if defined (SBH) Message_print(IDS_CTR_HOST, response[i].id, response[i].hostname); #else WlbsAddressToString(response[i].address, wbuf, &len); Message_print(IDS_CTR_HOST, response[i].id, wbuf); #endif } if (response[i].status == WLBS_BAD_PASSW) { if (target_host != CVY_ALL_HOSTS) { WConsole(L"\n"); Message_print(IDS_CTR_BAD_PASSW); } else { Message_print(IDS_CTR_BAD_PASSW_C); WConsole(L"\n"); } continue; } Report(command, TRUE, response[i].status, param1, param2, response[i].status, response[i].id, host_map); } return; } BOOL ParsePort( PWCHAR arg, PULONG pvip, PULONG pport ) /* arg is expected to optionally contain a virtual IP address or a "all", signifying the "all vip" port rule and mandatorilay contain "all", signifying all ports, or a port number in the range of 0-65535. Return: TRUE if valid parse, in which case *pvip & *pport contains the parsed value. FALSE if invalid parse, in which case *pvip & *pport are undefined. */ { BOOL fRet = TRUE; WCHAR vip_str[WLBS_MAX_CL_IP_ADDR+1]; WCHAR *temp_str; ULONG port, viplen; // Check if a vip or the "ALL" string was passed if ((temp_str = wcspbrk(arg,L":")) != NULL) { viplen = (ULONG)(temp_str - arg); wcsncpy(vip_str, arg, viplen); vip_str[viplen] = L'\0'; *pvip = IpAddressFromAbcdWsz(vip_str); // A vip was not passed, Check if the "All" string was passed if (*pvip == INADDR_NONE) { if (_wcsicmp (vip_str, L"all") == 0) { *pvip = IpAddressFromAbcdWsz(CVY_DEF_ALL_VIP); } else { return FALSE; } } arg = temp_str + 1; } else // Neither a vip nor the "All" string was passed, so this applies to every vip { *pvip = IOCTL_ALL_VIPS; } if (_wcsicmp (arg, L"all") == 0) { port = IOCTL_ALL_PORTS; } else { port = _wtoi (arg); if ( wcspbrk(arg, L".:") != NULL || (port == 0 && arg[0] != L'0') || port > 65535 ) fRet = FALSE; } *pport = port; return fRet; } /* * Function: Process_tracing * Description: This function processing the tracing command. * Author: shouse 12.12.00 * */ DWORD Process_tracing (DWORD tracing, TraceOutput output, DWORD flags) { HKEY hTracingKey; const WCHAR szTracingKey[] = L"Software\\Microsoft\\Tracing\\wlbs"; const WCHAR szDebuggerTracingEnableValue[] = L"EnableDebuggerTracing"; const WCHAR szDebuggerTracingMaskValue[] = L"DebuggerTracingMask"; const WCHAR szFileTracingEnableValue[] = L"EnableFileTracing"; const WCHAR szFileTracingMaskValue[] = L"FileTracingMask"; const WCHAR szConsoleTracingEnableValue[] = L"EnableConsoleTracing"; const WCHAR szConsoleTracingMaskValue[] = L"ConsoleTracingMask"; DWORD status = ERROR_SUCCESS; if ((status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szTracingKey, 0, KEY_ALL_ACCESS, &hTracingKey)) == ERROR_SUCCESS) { DWORD size = sizeof (DWORD); switch (output) { case TRACE_FILE: if ((status = RegSetValueEx(hTracingKey, szFileTracingEnableValue, 0, REG_DWORD, (LPBYTE)&tracing, size)) != ERROR_SUCCESS) break; if (tracing) if ((status = RegSetValueEx(hTracingKey, szFileTracingMaskValue, 0, REG_DWORD, (LPBYTE)&flags, size)) != ERROR_SUCCESS) break; break; case TRACE_CONSOLE: if ((status = RegSetValueEx(hTracingKey, szConsoleTracingEnableValue, 0, REG_DWORD, (LPBYTE)&tracing, size)) != ERROR_SUCCESS) break; if (tracing) if ((status = RegSetValueEx(hTracingKey, szConsoleTracingMaskValue, 0, REG_DWORD, (LPBYTE)&flags, size)) != ERROR_SUCCESS) break; break; case TRACE_DEBUGGER: if ((status = RegSetValueEx(hTracingKey, szDebuggerTracingEnableValue, 0, REG_DWORD, (LPBYTE)&tracing, size)) != ERROR_SUCCESS) break; if (tracing) if ((status = RegSetValueEx(hTracingKey, szDebuggerTracingMaskValue, 0, REG_DWORD, (LPBYTE)&flags, size)) != ERROR_SUCCESS) break; break; case TRACE_ALL: if ((status = RegSetValueEx(hTracingKey, szFileTracingEnableValue, 0, REG_DWORD, (LPBYTE)&tracing, size)) != ERROR_SUCCESS) break; if (tracing) if ((status = RegSetValueEx(hTracingKey, szFileTracingMaskValue, 0, REG_DWORD, (LPBYTE)&flags, size)) != ERROR_SUCCESS) break; if ((status = RegSetValueEx(hTracingKey, szConsoleTracingEnableValue, 0, REG_DWORD, (LPBYTE)&tracing, size)) != ERROR_SUCCESS) break; if (tracing) if ((status = RegSetValueEx(hTracingKey, szConsoleTracingMaskValue, 0, REG_DWORD, (LPBYTE)&flags, size)) != ERROR_SUCCESS) break; if ((status = RegSetValueEx(hTracingKey, szDebuggerTracingEnableValue, 0, REG_DWORD, (LPBYTE)&tracing, size)) != ERROR_SUCCESS) break; if (tracing) if ((status = RegSetValueEx(hTracingKey, szDebuggerTracingMaskValue, 0, REG_DWORD, (LPBYTE)&flags, size)) != ERROR_SUCCESS) break; break; } RegCloseKey(hTracingKey); } if (status == ERROR_SUCCESS) { switch (output) { case TRACE_FILE: if (tracing) Message_print(IDS_CTR_TRACE_FILE_ON); else Message_print(IDS_CTR_TRACE_FILE_OFF); break; case TRACE_CONSOLE: if (tracing) Message_print(IDS_CTR_TRACE_CONSOLE_ON); else Message_print(IDS_CTR_TRACE_CONSOLE_OFF); break; case TRACE_DEBUGGER: if (tracing) Message_print(IDS_CTR_TRACE_DEBUGGER_ON); else Message_print(IDS_CTR_TRACE_DEBUGGER_OFF); break; case TRACE_ALL: if (tracing) Message_print(IDS_CTR_TRACE_ALL_ON); else Message_print(IDS_CTR_TRACE_ALL_OFF); break; } if (tracing) { switch (flags) { case TL_ERROR: Message_print(IDS_CTR_TRACE_E); break; case TL_WARN: Message_print(IDS_CTR_TRACE_W); break; case TL_INFO: Message_print(IDS_CTR_TRACE_I); break; case TL_ERROR|TL_INFO: Message_print(IDS_CTR_TRACE_EI); break; case TL_ERROR|TL_WARN: Message_print(IDS_CTR_TRACE_EW); break; case TL_WARN|TL_INFO: Message_print(IDS_CTR_TRACE_WI); break; case TL_ERROR|TL_WARN|TL_INFO: Message_print(IDS_CTR_TRACE_EWI); break; } } } return status; } /* * Function: Parse_tracing * Description: This function parses the WLBS tracing control arguments. * Author: shouse 12.12.00 * */ BOOLEAN Parse_tracing (INT argc, PWCHAR argv [], PINT arg_index, PDWORD flags) { if (argc < 4) return TRUE; for (; (*arg_index) < argc; (*arg_index)++) { if ((_wcsicmp(argv[*arg_index] + 1, L"error") == 0)) { if (*(argv[*arg_index]) == '+') *flags |= TL_ERROR; else if (*(argv[*arg_index]) == '-') *flags &= ~TL_ERROR; else return FALSE; } else if ((_wcsicmp(argv[*arg_index] + 1, L"warning") == 0)) { if (*(argv[*arg_index]) == '+') *flags |= TL_WARN; else if (*(argv[*arg_index]) == '-') *flags &= ~TL_WARN; else return FALSE; } else if ((_wcsicmp(argv[*arg_index] + 1, L"info") == 0)) { if (*(argv[*arg_index]) == '+') *flags |= TL_INFO; else if (*(argv[*arg_index]) == '-') *flags &= ~TL_INFO; else return FALSE; } else return FALSE; } return TRUE; } extern "C" { int __cdecl wmain (int argc, PWCHAR argv[]) { INT arg_index; ULONG i, ip; PUCHAR bp; LONG status; DWORD target_cl; DWORD target_host; WLBS_COMMANDS command = invalid; ULONG param1; ULONG param2; ULONG dest_port; PWCHAR dest_password; DWORD dest_addr; _wsetlocale(LC_ALL, L".OCP"); if ((ConsoleHdl = GetStdHandle(STD_OUTPUT_HANDLE)) == INVALID_HANDLE_VALUE) { wprintf(L"GetStdHandle failed, Unable to write to Console !!!\n"); return CVY_ERROR_SYSTEM; } Message_print(IDS_CTR_NAME, CVY_NAME); if (argc < 2 || argc > 10) { usage: Message_print(IDS_CTR_USAGE, CVY_NAME); Message_print(IDS_CTR_USAGE2); return CVY_ERROR_USAGE; } status = WlbsInit(NULL, WLBS_API_VER, NULL); if (status == WLBS_INIT_ERROR) { Message_print(IDS_CTR_WSOCK); Error_print(TRUE); return CVY_ERROR_SYSTEM; } #if defined (SBH) /* 100 BEGIN hack. */ IOCTL_QUERY_STATE buf; buf.Operation = NLB_QUERY_PACKET_FILTER; buf.Filter.ServerIPAddress = WlbsResolve(L"12.12.4.2"); buf.Filter.ClientIPAddress = WlbsResolve(L"11.11.1.1"); buf.Filter.ServerPort = 80; buf.Filter.ClientPort = 17348; buf.Filter.Protocol = 6; DWORD myretval = WlbsQueryState(WlbsResolve(L"12.12.4.2"), CVY_ALL_HOSTS, &buf); return CVY_OK;; /* 110 END hack. */ #endif arg_index = 1; /* parse command */ if (_wcsicmp(argv [arg_index], L"ip2mac") == 0) { command = ip2mac; arg_index++; if (argc < 3) goto usage; ip = WlbsResolve(argv[arg_index]); bp = (PUCHAR)(&ip); Message_print(IDS_CTR_IP, inet_ntoa(*((struct in_addr *)&ip))); Message_print(IDS_CTR_MCAST, bp[0], bp[1], bp[2], bp[3]); Message_print(IDS_CTR_UCAST, bp[0], bp[1], bp[2], bp[3]); return CVY_OK; } else if (_wcsicmp(argv[arg_index], L"help") == 0) { command = help; swprintf(wbuf, L"%ls.chm", CVY_NAME); if (_wspawnlp(P_NOWAIT, L"hh.exe", L"hh.exe", wbuf, NULL) == -1) { Message_print(IDS_CTR_HELP); return CVY_ERROR_SYSTEM; } return CVY_OK; } else if (_wcsicmp(argv[arg_index], L"suspend") == 0) { command = suspend; arg_index++; #ifndef BACKWARD_COMPATIBILITY if (argc < 3) goto usage; #endif if (!Parse(argc, argv, &arg_index, &target_cl, &target_host)) goto usage; } else if (_wcsicmp(argv[arg_index], L"resume") == 0) { command = resume; arg_index++; #ifndef BACKWARD_COMPATIBILITY if (argc < 3) goto usage; #endif if (!Parse(argc, argv, &arg_index, &target_cl, &target_host)) goto usage; } else if (_wcsicmp(argv[arg_index], L"start") == 0) { command = __start; arg_index++; #ifndef BACKWARD_COMPATIBILITY if (argc < 3) goto usage; #endif if (!Parse(argc, argv, &arg_index, &target_cl, &target_host)) goto usage; } else if (_wcsicmp(argv[arg_index], L"stop") == 0) { command = stop; arg_index++; #ifndef BACKWARD_COMPATIBILITY if (argc < 3) goto usage; #endif if (!Parse(argc, argv, &arg_index, &target_cl, &target_host)) goto usage; } else if (_wcsicmp(argv[arg_index], L"drainstop") == 0) { command = drainstop; arg_index++; #ifndef BACKWARD_COMPATIBILITY if (argc < 3) goto usage; #endif if (!Parse(argc, argv, &arg_index, &target_cl, &target_host)) goto usage; } else if (_wcsicmp(argv[arg_index], L"query") == 0) { command = query; arg_index++; #ifndef BACKWARD_COMPATIBILITY if (argc < 3) goto usage; #endif if (!Parse(argc, argv, &arg_index, &target_cl, &target_host)) goto usage; } else if (_wcsicmp(argv[arg_index], L"enable") == 0) { command = enable; arg_index++; #ifdef BACKWARD_COMPATIBILITY if (argc < 3) #else if (argc < 4) #endif goto usage; if (!ParsePort(argv[arg_index], ¶m1, ¶m2)) goto usage; arg_index++; if (!Parse(argc, argv, &arg_index, &target_cl, &target_host)) goto usage; } else if (_wcsicmp(argv[arg_index], L"disable") == 0) { command = disable; arg_index++; #ifdef BACKWARD_COMPATIBILITY if (argc < 3) #else if (argc < 4) #endif goto usage; if (!ParsePort(argv[arg_index], ¶m1, ¶m2)) goto usage; arg_index++; if (!Parse(argc, argv, &arg_index, &target_cl, &target_host)) goto usage; } else if (_wcsicmp(argv[arg_index], L"drain") == 0) { command = drain; arg_index++; #ifdef BACKWARD_COMPATIBILITY if (argc < 3) #else if (argc < 4) #endif goto usage; if (!ParsePort(argv[arg_index], ¶m1, ¶m2)) goto usage; arg_index++; if (!Parse(argc, argv, &arg_index, &target_cl, &target_host)) goto usage; } /* local only commands */ else if (_wcsicmp(argv[arg_index], L"display") == 0) { command = display; arg_index++; target_host = CVY_LOCAL_HOST; // Verify that the cluster ip or "All" string is passed and there are no more arguments if ((arg_index == argc) || (arg_index + 1 < argc)) #ifdef BACKWARD_COMPATIBILITY if (arg_index == argc) target_cl = CVY_ALL_CLUSTERS; else goto usage; #else goto usage; #endif else { // Retrieve the Cluster IP Address or "ALL" if (_wcsicmp (argv[arg_index], L"all") == 0) { target_cl = CVY_ALL_CLUSTERS; } else { target_cl = WlbsResolve(argv [arg_index]); if (target_cl == 0) goto usage; } arg_index++; } } else if (_wcsicmp(argv[arg_index], L"reload") == 0) { command = reload; arg_index++; target_host = CVY_LOCAL_HOST; // Verify that the cluster ip or "All" string is passed and there are no more arguments if ((arg_index == argc) || (arg_index + 1 < argc)) #ifdef BACKWARD_COMPATIBILITY if (arg_index == argc) target_cl = CVY_ALL_CLUSTERS; else goto usage; #else goto usage; #endif else { // Retrieve the Cluster IP Address or "ALL" if (_wcsicmp (argv[arg_index], L"all") == 0) { target_cl = CVY_ALL_CLUSTERS; } else { target_cl = WlbsResolve(argv [arg_index]); if (target_cl == 0) goto usage; } arg_index++; } } else if (_wcsicmp(argv[arg_index], L"registry") == 0) { command = registry; target_host = CVY_LOCAL_HOST; arg_index++; if (argc < 4) goto reg_usage; if (_wcsicmp(argv[arg_index], L"mcastipaddress") == 0) { arg_index++; param1 = mcastipaddress; if (!(param2 = WlbsResolve(argv[arg_index]))) goto reg_usage; /* 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. */ if ((param2 & 0xf0) != 0xe0 || (param2 & 0x00ffff00) == 0 || (param2 & 0x00ffff00) == 0x00008000) { Message_print (IDS_CTR_REG_INVAL_MCASTIPADDRESS); goto reg_usage; } } else if (_wcsicmp(argv[arg_index], L"iptomcastip") == 0) { arg_index++; param1 = iptomcastip; if (_wcsicmp(argv[arg_index], L"on") == 0) param2 = 1; else if (_wcsicmp(argv[arg_index], L"off") == 0) param2 = 0; else goto reg_usage; } else if (_wcsicmp(argv[arg_index], L"masksrcmac") == 0) { arg_index++; param1 = masksrcmac; if (_wcsicmp(argv[arg_index], L"on") == 0) param2 = 1; else if (_wcsicmp(argv[arg_index], L"off") == 0) param2 = 0; else goto reg_usage; } else if (_wcsicmp(argv[arg_index], L"iptomacenable") == 0) { arg_index++; param1 = iptomacenable; if (_wcsicmp(argv[arg_index], L"on") == 0) param2 = 1; else if (_wcsicmp(argv[arg_index], L"off") == 0) param2 = 0; else goto reg_usage; } else { Message_print(IDS_CTR_REG_KEY, argv[arg_index]); goto reg_usage; } arg_index++; if (arg_index == argc) { target_cl = CVY_ALL_CLUSTERS; } else if (arg_index + 1 < argc) goto reg_usage; else { if (!(target_cl = WlbsResolve(argv[arg_index]))) goto reg_usage; arg_index++; } if (argc != arg_index) goto reg_usage; } else if (_wcsicmp(argv[arg_index], L"tracing") == 0) { TraceOutput output; DWORD flags = TL_ERROR; DWORD tracing = 0; arg_index++; if (argc < 3) goto trace_usage; if (_wcsicmp(argv[arg_index], L"file") == 0) output = TRACE_FILE; else if (_wcsicmp(argv[arg_index], L"console") == 0) output = TRACE_CONSOLE; else if (_wcsicmp(argv[arg_index], L"debugger") == 0) output = TRACE_DEBUGGER; else if (_wcsicmp(argv[arg_index], L"on") == 0) { output = TRACE_ALL; arg_index--; } else if (_wcsicmp(argv[arg_index], L"off") == 0) { output = TRACE_ALL; arg_index--; } else goto trace_usage; arg_index++; if (_wcsicmp(argv[arg_index], L"on") == 0) tracing = 1; else if (_wcsicmp(argv[arg_index], L"off") == 0) tracing = 0; else goto trace_usage; arg_index++; if (tracing && !Parse_tracing(argc, argv, &arg_index, &flags)) goto trace_usage; if (Process_tracing(tracing, output, flags) != ERROR_SUCCESS) Message_print(IDS_CTR_TRACE_FAILED); return CVY_OK; } else goto usage; /* The remote control parameters need to be parsed. */ dest_password = NULL; dest_addr = 0; dest_port = 0; while (arg_index < argc) { if (argv[arg_index][0] == L'/' || argv[arg_index][0] == L'-') { if (_wcsicmp(argv[arg_index] + 1, L"PASSW") == 0) { arg_index++; if (arg_index >= argc || argv[arg_index][0] == L'/' || argv[arg_index][0] == L'-') { HANDLE hConsole; DWORD dwMode; // console mode DWORD dwInputMode; // stdin input mode Message_print(IDS_CTR_PASSW); hConsole = GetStdHandle(STD_INPUT_HANDLE); dwInputMode = GetFileType(hConsole); // // prompt for password, making sure password isn't echoed // if the stdin is redirected, don't bother querying/changing console mode // if (dwInputMode == FILE_TYPE_CHAR) { if (!GetConsoleMode(hConsole, &dwMode)) { Error_print(FALSE); return CVY_ERROR_SYSTEM; } if (!SetConsoleMode(hConsole, dwMode &= ~ENABLE_ECHO_INPUT)) { Error_print(FALSE); return CVY_ERROR_SYSTEM; } } for (i = 0; i < CVY_STR_SIZE; i++) { // // read a character, copying to the buffer // break out of loop on CR and EOF // if ((psw_buf[i] = fgetwc(stdin)) == WEOF) break; if (psw_buf[i] == L'\n') break; } // NULL terminate the password psw_buf[i] = L'\0'; // restore previous console mode if (dwInputMode == FILE_TYPE_CHAR) SetConsoleMode(hConsole, dwMode); WConsole(L"\n"); if (i == 0) dest_password = NULL; else dest_password = psw_buf; } else { dest_password = argv[arg_index]; arg_index ++; } } else if (_wcsicmp(argv[arg_index] + 1, L"PORT") == 0) { arg_index++; if (arg_index >= argc || argv[arg_index][0] == L'/' || argv[arg_index][0] == L'-') goto usage; dest_port = (USHORT)_wtoi(argv[arg_index]); if (dest_port == 0) goto usage; arg_index++; } else if (_wcsicmp(argv[arg_index] + 1, L"DEST") == 0) { arg_index++; if (arg_index >= argc || argv[arg_index][0] == L'/' || argv[arg_index][0] == L'-') goto usage; dest_addr = WlbsResolve(argv [arg_index]); if (dest_addr == 0) goto usage; arg_index++; } else goto usage; } else goto usage; } if (target_cl != CVY_ALL_CLUSTERS) { Process(command, target_cl, target_host, param1, param2, dest_port, dest_addr, dest_password); return CVY_OK; } /* Enumerate all the clusters and call process for each one of them */ else { DWORD clusters[CVY_MAX_ADAPTERS]; DWORD i, len; len = CVY_MAX_ADAPTERS; WlbsEnumClusters(clusters, &len); if (!len) { Message_print(IDS_CTR_NO_CVY, CVY_NAME); return CVY_OK; } for (i = 0 ; i < len; i++) { WCHAR wbuf[CVY_STR_SIZE]; DWORD buflen = CVY_STR_SIZE; WlbsAddressToString(clusters[i], wbuf, &buflen); Message_print(IDS_CTR_CLUSTER_ID, wbuf); Process(command, clusters[i], target_host, param1, param2, dest_port, dest_addr, dest_password); if (i < len - 1) WConsole (L"\n"); } return CVY_OK; } reg_usage: Message_print(IDS_CTR_REG_USAGE, CVY_NAME); return CVY_ERROR_USAGE; trace_usage: Message_print(IDS_CTR_TRACE_USAGE, CVY_NAME); return CVY_ERROR_USAGE; } }