1898 lines
59 KiB
C++
1898 lines
59 KiB
C++
/*++
|
|
|
|
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 <windows.h>
|
|
#include <stdio.h>
|
|
#include <conio.h>
|
|
#include <stdlib.h>
|
|
#include <process.h>
|
|
#include <time.h>
|
|
#include <locale.h>
|
|
#include <winsock2.h>
|
|
#include <ws2tcpip.h>
|
|
#include <tchar.h>
|
|
#include <shlwapi.h>
|
|
|
|
#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;
|
|
}
|
|
|
|
}
|
|
|
|
|