softether-vpn/src/Cedar/EM.c

1494 lines
32 KiB
C

// SoftEther VPN Source Code - Stable Edition Repository
// Cedar Communication Module
//
// SoftEther VPN Server, Client and Bridge are free software under the Apache License, Version 2.0.
//
// Copyright (c) Daiyuu Nobori.
// Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan.
// Copyright (c) SoftEther Corporation.
// Copyright (c) all contributors on SoftEther VPN project in GitHub.
//
// All Rights Reserved.
//
// http://www.softether.org/
//
// This stable branch is officially managed by Daiyuu Nobori, the owner of SoftEther VPN Project.
// Pull requests should be sent to the Developer Edition Master Repository on https://github.com/SoftEtherVPN/SoftEtherVPN
//
// License: The Apache License, Version 2.0
// https://www.apache.org/licenses/LICENSE-2.0
//
// DISCLAIMER
// ==========
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, UNDER
// JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, MERGE, PUBLISH,
// DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS SOFTWARE, THAT ANY
// JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS SOFTWARE OR ITS CONTENTS,
// AGAINST US (SOFTETHER PROJECT, SOFTETHER CORPORATION, DAIYUU NOBORI OR OTHER
// SUPPLIERS), OR ANY JURIDICAL DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND
// OF USING, COPYING, MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING,
// AND/OR SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO EXCLUSIVE
// JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO, JAPAN. YOU MUST WAIVE
// ALL DEFENSES OF LACK OF PERSONAL JURISDICTION AND FORUM NON CONVENIENS.
// PROCESS MAY BE SERVED ON EITHER PARTY IN THE MANNER AUTHORIZED BY APPLICABLE
// LAW OR COURT RULE.
//
// USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS YOU HAVE
// A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY CRIMINAL LAWS OR CIVIL
// RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS SOFTWARE IN OTHER COUNTRIES IS
// COMPLETELY AT YOUR OWN RISK. THE SOFTETHER VPN PROJECT HAS DEVELOPED AND
// DISTRIBUTED THIS SOFTWARE TO COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING
// CIVIL RIGHTS INCLUDING PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER
// COUNTRIES' LAWS OR CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES.
// WE HAVE NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR
// INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+ COUNTRIES
// AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE WORLD, WITH
// DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY COUNTRIES' LAWS, REGULATIONS
// AND CIVIL RIGHTS TO MAKE THE SOFTWARE COMPLY WITH ALL COUNTRIES' LAWS BY THE
// PROJECT. EVEN IF YOU WILL BE SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A
// PUBLIC SERVANT IN YOUR COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE
// LIABLE TO RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL
// RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT JUST A
// STATEMENT FOR WARNING AND DISCLAIMER.
//
// READ AND UNDERSTAND THE 'WARNING.TXT' FILE BEFORE USING THIS SOFTWARE.
// SOME SOFTWARE PROGRAMS FROM THIRD PARTIES ARE INCLUDED ON THIS SOFTWARE WITH
// LICENSE CONDITIONS WHICH ARE DESCRIBED ON THE 'THIRD_PARTY.TXT' FILE.
//
//
// SOURCE CODE CONTRIBUTION
// ------------------------
//
// Your contribution to SoftEther VPN Project is much appreciated.
// Please send patches to us through GitHub.
// Read the SoftEther VPN Patch Acceptance Policy in advance:
// http://www.softether.org/5-download/src/9.patch
//
//
// DEAR SECURITY EXPERTS
// ---------------------
//
// If you find a bug or a security vulnerability please kindly inform us
// about the problem immediately so that we can fix the security problem
// to protect a lot of users around the world as soon as possible.
//
// Our e-mail address for security reports is:
// softether-vpn-security [at] softether.org
//
// Please note that the above e-mail address is not a technical support
// inquiry address. If you need technical assistance, please visit
// http://www.softether.org/ and ask your question on the users forum.
//
// Thank you for your cooperation.
//
//
// NO MEMORY OR RESOURCE LEAKS
// ---------------------------
//
// The memory-leaks and resource-leaks verification under the stress
// test has been passed before release this source code.
// EM.c
// EtherLogger Manager for Win32
#include <GlobalConst.h>
#ifdef WIN32
#define SM_C
#define CM_C
#define NM_C
#define EM_C
#define _WIN32_WINNT 0x0502
#define WINVER 0x0502
#include <winsock2.h>
#include <windows.h>
#include <wincrypt.h>
#include <wininet.h>
#include <shlobj.h>
#include <commctrl.h>
#include <Dbghelp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <stdarg.h>
#include <time.h>
#include <errno.h>
#include <Mayaqua/Mayaqua.h>
#include <Cedar/Cedar.h>
#include "CMInner.h"
#include "SMInner.h"
#include "NMInner.h"
#include "EMInner.h"
#include "../PenCore/resource.h"
// License registration process
void EmLicenseAddDlgOnOk(HWND hWnd, RPC *s)
{
}
// Shift treatment of text input
void EmLicenseAddDlgShiftTextItem(HWND hWnd, UINT id1, UINT id2, UINT *next_focus)
{
char *s;
// Validate arguments
if (hWnd == NULL || next_focus == NULL)
{
return;
}
s = GetTextA(hWnd, id1);
if (StrLen(s) >= 6)
{
char *s2 = CopyStr(s);
char tmp[MAX_SIZE];
s2[6] = 0;
SetTextA(hWnd, id1, s2);
Free(s2);
if (id2 != 0)
{
GetTxtA(hWnd, id2, tmp, sizeof(tmp));
StrCat(tmp, sizeof(tmp), s + 6);
ReplaceStrEx(tmp, sizeof(tmp), tmp, "-", "", false);
SetTextA(hWnd, id2, tmp);
*next_focus = id2;
}
else
{
*next_focus = IDOK;
}
}
Free(s);
}
// Make a text from the input data
void EmLicenseAddDlgGetText(HWND hWnd, char *str, UINT size)
{
char *k1, *k2, *k3, *k4, *k5, *k6;
// Validate arguments
if (hWnd == NULL || str == NULL)
{
return;
}
k1 = GetTextA(hWnd, B_KEY1);
k2 = GetTextA(hWnd, B_KEY2);
k3 = GetTextA(hWnd, B_KEY3);
k4 = GetTextA(hWnd, B_KEY4);
k5 = GetTextA(hWnd, B_KEY5);
k6 = GetTextA(hWnd, B_KEY6);
Format(str, size, "%s-%s-%s-%s-%s-%s", k1, k2, k3, k4, k5, k6);
Free(k1);
Free(k2);
Free(k3);
Free(k4);
Free(k5);
Free(k6);
}
// License addition dialog update
void EmLicenseAddDlgUpdate(HWND hWnd, RPC *s)
{
}
// License addition dialog initialization
void EmLicenseAddDlgInit(HWND hWnd, RPC *s)
{
HFONT h;
// Validate arguments
if (hWnd == NULL || s == NULL)
{
return;
}
h = GetFont("Arial", 10, true, false, false, false);
SetFont(hWnd, B_KEY1, h);
SetFont(hWnd, B_KEY2, h);
SetFont(hWnd, B_KEY3, h);
SetFont(hWnd, B_KEY4, h);
SetFont(hWnd, B_KEY5, h);
SetFont(hWnd, B_KEY6, h);
DlgFont(hWnd, S_INFO, 10, true);
EmLicenseAddDlgUpdate(hWnd, s);
}
// License addition dialog
UINT EmLicenseAddDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
{
RPC *s = (RPC *)param;
// Validate arguments
if (hWnd == NULL)
{
return 0;
}
switch (msg)
{
case WM_INITDIALOG:
EmLicenseAddDlgInit(hWnd, s);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case B_KEY1:
case B_KEY2:
case B_KEY3:
case B_KEY4:
case B_KEY5:
case B_KEY6:
switch (HIWORD(wParam))
{
case EN_CHANGE:
EmLicenseAddDlgUpdate(hWnd, s);
switch (LOWORD(wParam))
{
case B_KEY2:
if (GetTextLen(hWnd, B_KEY2, true) == 0)
{
FocusEx(hWnd, B_KEY1);
}
break;
case B_KEY3:
if (GetTextLen(hWnd, B_KEY3, true) == 0)
{
FocusEx(hWnd, B_KEY2);
}
break;
case B_KEY4:
if (GetTextLen(hWnd, B_KEY4, true) == 0)
{
FocusEx(hWnd, B_KEY3);
}
break;
case B_KEY5:
if (GetTextLen(hWnd, B_KEY5, true) == 0)
{
FocusEx(hWnd, B_KEY4);
}
break;
case B_KEY6:
if (GetTextLen(hWnd, B_KEY6, true) == 0)
{
FocusEx(hWnd, B_KEY5);
}
break;
}
break;
}
break;
}
switch (wParam)
{
case IDOK:
EmLicenseAddDlgOnOk(hWnd, s);
break;
case IDCANCEL:
Close(hWnd);
break;
}
break;
case WM_CLOSE:
EndDialog(hWnd, 0);
break;
}
return 0;
}
// Add a license
bool EmLicenseAdd(HWND hWnd, RPC *s)
{
// Validate arguments
if (s == NULL)
{
return false;
}
return Dialog(hWnd, D_EM_LICENSE_ADD, EmLicenseAddDlg, s);
}
// License dialog initialization
void EmLicenseDlgInit(HWND hWnd, RPC *s)
{
// Validate arguments
if (hWnd == NULL || s == NULL)
{
return;
}
SetIcon(hWnd, 0, ICO_CERT);
DlgFont(hWnd, S_BOLD, 0, true);
DlgFont(hWnd, S_BOLD2, 0, true);
LvInit(hWnd, L_LIST);
LvSetStyle(hWnd, L_LIST, LVS_EX_GRIDLINES);
LvInsertColumn(hWnd, L_LIST, 0, _UU("SM_LICENSE_COLUMN_1"), 50);
LvInsertColumn(hWnd, L_LIST, 1, _UU("SM_LICENSE_COLUMN_2"), 100);
LvInsertColumn(hWnd, L_LIST, 2, _UU("SM_LICENSE_COLUMN_3"), 290);
LvInsertColumn(hWnd, L_LIST, 3, _UU("SM_LICENSE_COLUMN_4"), 150);
LvInsertColumn(hWnd, L_LIST, 4, _UU("SM_LICENSE_COLUMN_5"), 120);
LvInsertColumn(hWnd, L_LIST, 5, _UU("SM_LICENSE_COLUMN_6"), 250);
LvInsertColumn(hWnd, L_LIST, 6, _UU("SM_LICENSE_COLUMN_7"), 100);
LvInsertColumn(hWnd, L_LIST, 7, _UU("SM_LICENSE_COLUMN_8"), 100);
LvInsertColumn(hWnd, L_LIST, 8, _UU("SM_LICENSE_COLUMN_9"), 100);
LvInitEx(hWnd, L_STATUS, true);
LvInsertColumn(hWnd, L_STATUS, 0, _UU("SM_STATUS_COLUMN_1"), 100);
LvInsertColumn(hWnd, L_STATUS, 1, _UU("SM_STATUS_COLUMN_2"), 100);
EmLicenseDlgRefresh(hWnd, s);
}
// License dialog update
void EmLicenseDlgRefresh(HWND hWnd, RPC *s)
{
RPC_ENUM_LICENSE_KEY t;
RPC_EL_LICENSE_STATUS st;
UINT i;
wchar_t tmp[MAX_SIZE];
LVB *b;
// Validate arguments
if (hWnd == NULL || s == NULL)
{
return;
}
Zero(&t, sizeof(t));
if (CALL(hWnd, EcEnumLicenseKey(s, &t)) == false)
{
Close(hWnd);
return;
}
b = LvInsertStart();
for (i = 0;i < t.NumItem;i++)
{
wchar_t tmp1[32], tmp2[LICENSE_KEYSTR_LEN + 1], tmp3[LICENSE_MAX_PRODUCT_NAME_LEN + 1],
*tmp4, tmp5[128], tmp6[LICENSE_LICENSEID_STR_LEN + 1], tmp7[64],
tmp8[64], tmp9[64];
RPC_ENUM_LICENSE_KEY_ITEM *e = &t.Items[i];
UniToStru(tmp1, e->Id);
StrToUni(tmp2, sizeof(tmp2), e->LicenseKey);
StrToUni(tmp3, sizeof(tmp3), e->LicenseName);
tmp4 = LiGetLicenseStatusStr(e->Status);
if (e->Expires == 0)
{
UniStrCpy(tmp5, sizeof(tmp5), _UU("SM_LICENSE_NO_EXPIRES"));
}
else
{
GetDateStrEx64(tmp5, sizeof(tmp5), e->Expires, NULL);
}
StrToUni(tmp6, sizeof(tmp6), e->LicenseId);
UniToStru(tmp7, e->ProductId);
UniFormat(tmp8, sizeof(tmp8), L"%I64u", e->SystemId);
UniToStru(tmp9, e->SerialId);
LvInsertAdd(b,
e->Status == LICENSE_STATUS_OK ? ICO_PASS : ICO_DISCARD,
(void *)e->Id, 9,
tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9);
}
LvInsertEnd(b, hWnd, L_LIST);
FreeRpcEnumLicenseKey(&t);
Zero(&st, sizeof(st));
if (CALL(hWnd, EcGetLicenseStatus(s, &st)) == false)
{
Close(hWnd);
return;
}
b = LvInsertStart();
if (st.Valid == false)
{
LvInsertAdd(b, 0, NULL, 2, _UU("EM_NO_LICENSE_COLUMN"), _UU("EM_NO_LICENSE"));
}
else
{
// Current system ID
UniFormat(tmp, sizeof(tmp), L"%I64u", st.SystemId);
LvInsertAdd(b, 0, NULL, 2, _UU("SM_LICENSE_STATUS_SYSTEM_ID"), tmp);
// Expiration date of the current license product
if (st.SystemExpires == 0)
{
UniStrCpy(tmp, sizeof(tmp), _UU("SM_LICENSE_NO_EXPIRES"));
}
else
{
GetDateStrEx64(tmp, sizeof(tmp), st.SystemExpires, NULL);
}
LvInsertAdd(b, 0, NULL, 2, _UU("SM_LICENSE_STATUS_EXPIRES"), tmp);
}
LvInsertEnd(b, hWnd, L_STATUS);
if (LvNum(hWnd, L_STATUS) >= 1)
{
LvAutoSize(hWnd, L_STATUS);
}
EmLicenseDlgUpdate(hWnd, s);
}
// License dialog control update
void EmLicenseDlgUpdate(HWND hWnd, RPC *s)
{
bool b = false;
// Validate arguments
if (hWnd == NULL || s == NULL)
{
return;
}
b = LvIsSingleSelected(hWnd, L_LIST);
SetEnable(hWnd, B_DEL, b);
SetEnable(hWnd, IDOK, b);
}
// License dialog
UINT EmLicenseDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
{
RPC *s = (RPC *)param;
NMHDR *n;
// Validate arguments
if (hWnd == NULL)
{
return 0;
}
switch (msg)
{
case WM_INITDIALOG:
EmLicenseDlgInit(hWnd, s);
break;
case WM_NOTIFY:
n = (NMHDR *)lParam;
switch (n->code)
{
case LVN_ITEMCHANGED:
switch (n->idFrom)
{
case L_LIST:
case L_STATUS:
EmLicenseDlgUpdate(hWnd, s);
break;
}
break;
}
break;
case WM_COMMAND:
switch (wParam)
{
case IDOK:
if (IsEnable(hWnd, IDOK))
{
UINT i = LvGetSelected(hWnd, L_LIST);
if (i != INFINITE)
{
char *s = LvGetStrA(hWnd, L_LIST, i, 5);
char tmp[MAX_SIZE];
Format(tmp, sizeof(tmp), _SS("LICENSE_SUPPORT_URL"), s);
ShellExecute(hWnd, "open", tmp, NULL, NULL, SW_SHOW);
Free(s);
}
}
break;
case B_OBTAIN:
ShellExecute(hWnd, "open", _SS("LICENSE_INFO_URL"), NULL, NULL, SW_SHOW);
break;
case B_ADD:
if (EmLicenseAdd(hWnd, s))
{
EmLicenseDlgRefresh(hWnd, s);
}
break;
case B_DEL:
if (IsEnable(hWnd, B_DEL))
{
UINT id = (UINT)LvGetParam(hWnd, L_LIST, LvGetSelected(hWnd, L_LIST));
if (id != 0)
{
if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("SM_LICENSE_DELETE_MSG")) == IDYES)
{
RPC_TEST t;
Zero(&t, sizeof(t));
t.IntValue = id;
if (CALL(hWnd, EcDelLicenseKey(s, &t)))
{
EmLicenseDlgRefresh(hWnd, s);
}
}
}
}
break;
case IDCANCEL:
Close(hWnd);
break;
}
break;
case WM_CLOSE:
EndDialog(hWnd, 0);
break;
}
LvStandardHandler(hWnd, msg, wParam, lParam, L_LIST);
return 0;
}
// Change Password dialog
UINT EmPasswordDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
{
RPC *r = (RPC *)param;
char pass1[MAX_PATH];
char pass2[MAX_PATH];
UCHAR hash[SHA1_SIZE];
RPC_SET_PASSWORD t;
// Validate arguments
if (hWnd == NULL)
{
return 0;
}
switch (msg)
{
case WM_INITDIALOG:
Focus(hWnd, E_PASSWORD1);
break;
case WM_COMMAND:
switch (wParam)
{
case IDOK:
GetTxtA(hWnd, E_PASSWORD1, pass1, sizeof(pass1));
Hash(hash, pass1, StrLen(pass1), true);
Zero(&t, sizeof(t));
Copy(t.HashedPassword, hash, SHA1_SIZE);
if (CALL(hWnd, EcSetPassword(r, &t)) == false)
{
break;
}
MsgBox(hWnd, MB_ICONINFORMATION, _UU("CM_PASSWORD_SET"));
EndDialog(hWnd, 1);
break;
case IDCANCEL:
Close(hWnd);
break;
}
switch (LOWORD(wParam))
{
case E_PASSWORD1:
case E_PASSWORD2:
GetTxtA(hWnd, E_PASSWORD1, pass1, sizeof(pass1));
GetTxtA(hWnd, E_PASSWORD2, pass2, sizeof(pass2));
SetEnable(hWnd, IDOK, StrCmp(pass1, pass2) == 0 ? true : false);
break;
}
break;
case WM_CLOSE:
EndDialog(hWnd, 0);
break;
}
return 0;
}
// Copy the state of the dialog to the HUB_LOG
void EmDlgToHubLog(HWND hWnd, HUB_LOG *g)
{
// Validate arguments
if (hWnd == NULL || g == NULL)
{
return;
}
Zero(g, sizeof(HUB_LOG));
g->PacketLogSwitchType = CbGetSelect(hWnd, C_PACKET_SWITCH);
g->PacketLogConfig[0] = IsChecked(hWnd, B_PACKET_0_0) ? 0 : IsChecked(hWnd, B_PACKET_0_1) ? 1 : 2;
g->PacketLogConfig[1] = IsChecked(hWnd, B_PACKET_1_0) ? 0 : IsChecked(hWnd, B_PACKET_1_1) ? 1 : 2;
g->PacketLogConfig[2] = IsChecked(hWnd, B_PACKET_2_0) ? 0 : IsChecked(hWnd, B_PACKET_2_1) ? 1 : 2;
g->PacketLogConfig[3] = IsChecked(hWnd, B_PACKET_3_0) ? 0 : IsChecked(hWnd, B_PACKET_3_1) ? 1 : 2;
g->PacketLogConfig[4] = IsChecked(hWnd, B_PACKET_4_0) ? 0 : IsChecked(hWnd, B_PACKET_4_1) ? 1 : 2;
g->PacketLogConfig[5] = IsChecked(hWnd, B_PACKET_5_0) ? 0 : IsChecked(hWnd, B_PACKET_5_1) ? 1 : 2;
g->PacketLogConfig[6] = IsChecked(hWnd, B_PACKET_6_0) ? 0 : IsChecked(hWnd, B_PACKET_6_1) ? 1 : 2;
g->PacketLogConfig[7] = IsChecked(hWnd, B_PACKET_7_0) ? 0 : IsChecked(hWnd, B_PACKET_7_1) ? 1 : 2;
}
// Copy the HUB_LOG to the state of the dialog
void EmHubLogToDlg(HWND hWnd, HUB_LOG *g)
{
// Validate arguments
if (hWnd == NULL || g == NULL)
{
return;
}
CbSelect(hWnd, C_PACKET_SWITCH, g->PacketLogSwitchType);
Check(hWnd, B_PACKET_0_0, g->PacketLogConfig[0] == 0);
Check(hWnd, B_PACKET_0_1, g->PacketLogConfig[0] == 1);
Check(hWnd, B_PACKET_0_2, g->PacketLogConfig[0] == 2);
Check(hWnd, B_PACKET_1_0, g->PacketLogConfig[1] == 0);
Check(hWnd, B_PACKET_1_1, g->PacketLogConfig[1] == 1);
Check(hWnd, B_PACKET_1_2, g->PacketLogConfig[1] == 2);
Check(hWnd, B_PACKET_2_0, g->PacketLogConfig[2] == 0);
Check(hWnd, B_PACKET_2_1, g->PacketLogConfig[2] == 1);
Check(hWnd, B_PACKET_2_2, g->PacketLogConfig[2] == 2);
Check(hWnd, B_PACKET_3_0, g->PacketLogConfig[3] == 0);
Check(hWnd, B_PACKET_3_1, g->PacketLogConfig[3] == 1);
Check(hWnd, B_PACKET_3_2, g->PacketLogConfig[3] == 2);
Check(hWnd, B_PACKET_4_0, g->PacketLogConfig[4] == 0);
Check(hWnd, B_PACKET_4_1, g->PacketLogConfig[4] == 1);
Check(hWnd, B_PACKET_4_2, g->PacketLogConfig[4] == 2);
Check(hWnd, B_PACKET_5_0, g->PacketLogConfig[5] == 0);
Check(hWnd, B_PACKET_5_1, g->PacketLogConfig[5] == 1);
Check(hWnd, B_PACKET_5_2, g->PacketLogConfig[5] == 2);
Check(hWnd, B_PACKET_6_0, g->PacketLogConfig[6] == 0);
Check(hWnd, B_PACKET_6_1, g->PacketLogConfig[6] == 1);
Check(hWnd, B_PACKET_6_2, g->PacketLogConfig[6] == 2);
Check(hWnd, B_PACKET_7_0, g->PacketLogConfig[7] == 0);
Check(hWnd, B_PACKET_7_1, g->PacketLogConfig[7] == 1);
Check(hWnd, B_PACKET_7_2, g->PacketLogConfig[7] == 2);
}
// Initialize
void EmAddInit(HWND hWnd, EM_ADD *p)
{
// Validate arguments
if (hWnd == NULL || p == NULL)
{
return;
}
// Initialize controls
CbAddStr(hWnd, C_PACKET_SWITCH, _UU("SM_LOG_SWITCH_0"), 0);
CbAddStr(hWnd, C_PACKET_SWITCH, _UU("SM_LOG_SWITCH_1"), 1);
CbAddStr(hWnd, C_PACKET_SWITCH, _UU("SM_LOG_SWITCH_2"), 2);
CbAddStr(hWnd, C_PACKET_SWITCH, _UU("SM_LOG_SWITCH_3"), 3);
CbAddStr(hWnd, C_PACKET_SWITCH, _UU("SM_LOG_SWITCH_4"), 4);
CbAddStr(hWnd, C_PACKET_SWITCH, _UU("SM_LOG_SWITCH_5"), 5);
if (p->NewMode)
{
// Newly creation mode
RPC_ENUM_DEVICE t;
HUB_LOG g;
Zero(&g, sizeof(g));
g.PacketLogSwitchType = LOG_SWITCH_DAY;
g.PacketLogConfig[PACKET_LOG_TCP_CONN] = g.PacketLogConfig[PACKET_LOG_DHCP] = 1;
EmHubLogToDlg(hWnd, &g);
Zero(&t, sizeof(t));
if (CALL(hWnd, EcEnumAllDevice(p->Rpc, &t)))
{
UINT i;
CbSetHeight(hWnd, C_DEVICE, 18);
for (i = 0;i < t.NumItem;i++)
{
RPC_ENUM_DEVICE_ITEM *dev = &t.Items[i];
wchar_t tmp[MAX_SIZE];
StrToUni(tmp, sizeof(tmp), dev->DeviceName);
CbAddStr(hWnd, C_DEVICE, tmp, 0);
}
FreeRpcEnumDevice(&t);
}
SetText(hWnd, 0, _UU("EM_ADD_NEW"));
}
else
{
// Edit mode (to obtain a configuration)
wchar_t tmp[MAX_PATH];
RPC_ADD_DEVICE t;
Hide(hWnd, R_PROMISCUS);
Zero(&t, sizeof(t));
StrCpy(t.DeviceName, sizeof(t.DeviceName), p->DeviceName);
if (CALL(hWnd, EcGetDevice(p->Rpc, &t)))
{
EmHubLogToDlg(hWnd, &t.LogSetting);
}
else
{
Close(hWnd);
}
StrToUni(tmp, sizeof(tmp), p->DeviceName);
CbAddStr(hWnd, C_DEVICE, tmp, 0);
Disable(hWnd, C_DEVICE);
SetText(hWnd, 0, _UU("EM_ADD_EDIT"));
}
EmAddUpdate(hWnd, p);
}
// [OK] button
void EmAddOk(HWND hWnd, EM_ADD *p)
{
RPC_ADD_DEVICE t;
wchar_t *tmp;
char *name;
// Validate arguments
if (hWnd == NULL || p == NULL)
{
return;
}
Zero(&t, sizeof(t));
EmDlgToHubLog(hWnd, &t.LogSetting);
tmp = CbGetStr(hWnd, C_DEVICE);
name = CopyUniToStr(tmp);
StrCpy(t.DeviceName, sizeof(t.DeviceName), name);
if (p->NewMode)
{
t.NoPromiscus = IsChecked(hWnd, R_PROMISCUS);
}
if (p->NewMode)
{
if (CALL(hWnd, EcAddDevice(p->Rpc, &t)))
{
Close(hWnd);
}
}
else
{
if (CALL(hWnd, EcSetDevice(p->Rpc, &t)))
{
Close(hWnd);
}
}
Free(name);
Free(tmp);
}
// Control update
void EmAddUpdate(HWND hWnd, EM_ADD *p)
{
wchar_t *tmp;
char *name;
// Validate arguments
if (hWnd == NULL || p == NULL)
{
return;
}
tmp = CbGetStr(hWnd, C_DEVICE);
name = CopyUniToStr(tmp);
Trim(name);
if (StrLen(name) == 0)
{
Disable(hWnd, IDOK);
}
else
{
Enable(hWnd, IDCANCEL);
}
Free(name);
Free(tmp);
}
// Device Add / Edit dialog
UINT EmAddDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
{
EM_ADD *p = (EM_ADD *)param;
// Validate arguments
if (hWnd == NULL)
{
return 0;
}
switch (msg)
{
case WM_INITDIALOG:
EmAddInit(hWnd, p);
break;
case WM_COMMAND:
EmAddUpdate(hWnd, p);
switch (wParam)
{
case IDOK:
EmAddOk(hWnd, p);
break;
case IDCANCEL:
Close(hWnd);
break;
}
break;
case WM_CLOSE:
EndDialog(hWnd, 0);
break;
}
return 0;
}
// Add or edit
void EmAdd(HWND hWnd, RPC *r, char *device_name)
{
EM_ADD p;
// Validate arguments
if (hWnd == NULL || r == NULL)
{
return;
}
Zero(&p, sizeof(p));
p.Rpc = r;
if (device_name != NULL)
{
StrCpy(p.DeviceName, sizeof(p.DeviceName), device_name);
}
else
{
p.NewMode = true;
}
Dialog(hWnd, D_EM_ADD, EmAddDlg, &p);
}
// Initialize
void EmMainInit(HWND hWnd, RPC *r)
{
// Validate arguments
if (hWnd == NULL || r == NULL)
{
return;
}
LvInit(hWnd, L_LIST);
LvInsertColumn(hWnd, L_LIST, 0, _UU("EM_MAIN_COLUMN_1"), 300);
LvInsertColumn(hWnd, L_LIST, 1, _UU("EM_MAIN_COLUMN_2"), 150);
SetIcon(hWnd, 0, ICO_NIC_ONLINE);
EmMainRefresh(hWnd, r);
SetTimer(hWnd, 1, 1000, NULL);
}
// Control update
void EmMainUpdate(HWND hWnd, RPC *r)
{
// Validate arguments
if (hWnd == NULL || r == NULL)
{
return;
}
SetEnable(hWnd, IDOK, LvIsMasked(hWnd, L_LIST) && LvIsMultiMasked(hWnd, L_LIST) == false);
SetEnable(hWnd, B_DELETE, LvIsMasked(hWnd, L_LIST) && LvIsMultiMasked(hWnd, L_LIST) == false);
}
// Update
void EmMainRefresh(HWND hWnd, RPC *r)
{
RPC_ENUM_DEVICE t;
// Validate arguments
if (hWnd == NULL || r == NULL)
{
return;
}
Zero(&t, sizeof(t));
if (CALL(hWnd, EcEnumDevice(r, &t)))
{
UINT i;
LVB *b;
b = LvInsertStart();
for (i = 0;i < t.NumItem;i++)
{
wchar_t tmp[MAX_PATH];
RPC_ENUM_DEVICE_ITEM *dev = &t.Items[i];
StrToUni(tmp, sizeof(tmp), dev->DeviceName);
LvInsertAdd(b,
dev->Active ? ICO_NIC_ONLINE : ICO_NIC_OFFLINE,
NULL,
2,
tmp,
dev->Active ? _UU("EM_MAIN_OK") : _UU("EM_MAIN_ERROR"));
}
LvInsertEnd(b, hWnd, L_LIST);
FreeRpcEnumDevice(&t);
SetShow(hWnd, B_LICENSE, t.IsLicenseSupported);
}
else
{
Close(hWnd);
}
EmMainUpdate(hWnd, r);
}
// Main dialog procedure
UINT EmMainDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
{
NMHDR *n;
RPC *r = (RPC *)param;
UINT i;
char *name;
// Validate arguments
if (hWnd == NULL)
{
return 0;
}
switch (msg)
{
case WM_INITDIALOG:
EmMainInit(hWnd, r);
break;
case WM_COMMAND:
switch (wParam)
{
case IDOK:
// Edit
i = LvGetSelected(hWnd, L_LIST);
if (i != INFINITE)
{
wchar_t *tmp;
tmp = LvGetStr(hWnd, L_LIST, i, 0);
if (tmp != NULL)
{
name = CopyUniToStr(tmp);
EmAdd(hWnd, r, name);
Free(tmp);
Free(name);
}
}
break;
case B_PASSWORD:
// Admin password
Dialog(hWnd, D_EM_PASSWORD, EmPasswordDlg, r);
break;
case B_LICENSE:
// Admin password
Dialog(hWnd, D_EM_LICENSE, EmLicenseDlg, r);
break;
case B_ADD:
// Add
EmAdd(hWnd, r, NULL);
EmMainRefresh(hWnd, r);
break;
case B_DELETE:
// Delete
i = LvGetSelected(hWnd, L_LIST);
if (i != INFINITE)
{
wchar_t *tmp;
tmp = LvGetStr(hWnd, L_LIST, i, 0);
if (tmp != NULL)
{
RPC_DELETE_DEVICE t;
wchar_t msg[MAX_SIZE];
name = CopyUniToStr(tmp);
UniFormat(msg, sizeof(msg), _UU("EM_DELETE_CONFIRM"), name);
if (MsgBox(hWnd, MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2, msg) == IDYES)
{
Zero(&t, sizeof(t));
StrCpy(t.DeviceName, sizeof(t.DeviceName), name);
if (CALL(hWnd, EcDelDevice(r, &t)))
{
EmMainRefresh(hWnd, r);
}
}
Free(tmp);
Free(name);
}
}
break;
case IDCANCEL:
Close(hWnd);
break;
}
break;
case WM_TIMER:
switch (wParam)
{
case 1:
KillTimer(hWnd, 1);
EmMainRefresh(hWnd, r);
SetTimer(hWnd, 1, 1000, NULL);
break;
}
break;
case WM_NOTIFY:
n = (NMHDR *)lParam;
switch (n->code)
{
case NM_DBLCLK:
switch (n->idFrom)
{
case L_LIST:
if (IsEnable(hWnd, IDOK))
{
Command(hWnd, IDOK);
}
break;
}
break;
case LVN_ITEMCHANGED:
switch (n->idFrom)
{
case L_LIST:
EmMainUpdate(hWnd, r);
break;
}
break;
}
break;
case WM_CLOSE:
EndDialog(hWnd, 0);
break;
}
return 0;
}
// Installation of WinPcap
void EmInstallWinPcap(HWND hWnd, RPC *r)
{
wchar_t temp_name[MAX_SIZE];
HGLOBAL g;
HINSTANCE h;
HRSRC hr;
UINT size;
void *data;
IO *io;
// Ask whether the user want to start the installation
if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO, _UU("EM_WPCAP_INSTALL")) == IDNO)
{
return;
}
// Generate a temporary file name
UniFormat(temp_name, sizeof(temp_name), L"%s\\winpcap_installer.exe", MsGetTempDirW());
// Read from the resource
h = GetUiDll();
hr = FindResource(h, MAKEINTRESOURCE(BIN_WINPCAP), "BIN");
if (hr == NULL)
{
RES_ERROR:
MsgBox(hWnd, MB_ICONSTOP, _UU("EM_RESOURCE"));
return;
}
g = LoadResource(h, hr);
if (g == NULL)
{
goto RES_ERROR;
}
size = SizeofResource(h, hr);
data = LockResource(g);
if (data == NULL)
{
goto RES_ERROR;
}
// Write to a temporary file
io = FileCreateW(temp_name);
if (io == NULL)
{
goto RES_ERROR;
}
FileWrite(io, data, size);
FileClose(io);
// Run
if (RunW(temp_name, NULL, false, true) == false)
{
// Failure
FileDeleteW(temp_name);
goto RES_ERROR;
}
FileDeleteW(temp_name);
if (r == NULL)
{
return;
}
// Message after the end
if (OS_IS_WINDOWS_NT(GetOsInfo()->OsType) == false)
{
// Need to restart the computer
MsgBox(hWnd, MB_ICONINFORMATION, _UU("EM_WPCAP_REBOOT1"));
}
else
{
// Need to restart the service
if (MsgBox(hWnd, MB_ICONQUESTION | MB_YESNO, _UU("EM_WPCAP_REBOOT2")) == IDNO)
{
// Not restart
}
else
{
// Restart
RPC_TEST t;
RPC_BRIDGE_SUPPORT t2;
Zero(&t, sizeof(t));
EcRebootServer(r, &t);
SleepThread(500);
Zero(&t2, sizeof(t2));
CALL(hWnd, EcGetBridgeSupport(r, &t2));
}
}
}
// Main screen
void EMMain(RPC *r)
{
RPC_BRIDGE_SUPPORT t;
// Validate arguments
if (r == NULL)
{
return;
}
// Examine the bridge support status of the server side first
Zero(&t, sizeof(t));
if (CALLEX(NULL, ScGetBridgeSupport(r, &t)) == ERR_NO_ERROR)
{
if (t.IsBridgeSupportedOs == false)
{
// OS does not support the bridge
MsgBox(NULL, MB_ICONEXCLAMATION, _UU("EM_UNSUPPORTED"));
return;
}
if (t.IsWinPcapNeeded)
{
if (r->Sock->RemoteIP.addr[0] != 127)
{
// WinPcap is required, but can not do anything because it is in remote management mode
MsgBox(NULL, MB_ICONINFORMATION, _UU("EM_WPCAP_REMOTE"));
return;
}
else
{
// WinPcap is required, and it's in local management mode
if (MsIsAdmin())
{
// Administrators
EmInstallWinPcap(NULL, r);
return;
}
else
{
// Non-Administrators
MsgBox(NULL, MB_ICONINFORMATION, _UU("EM_WPCAP_ROOT"));
return;
}
}
}
}
Dialog(NULL, D_EM_MAIN, EmMainDlg, r);
}
// Remote connection dialog procedure
UINT EmRemoteDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *param)
{
WINUI_REMOTE *r = (WINUI_REMOTE *)param;
CEDAR *c;
// Validate arguments
if (hWnd == NULL)
{
return 0;
}
switch (msg)
{
case WM_INITDIALOG:
RemoteDlgInit(hWnd, r);
SetTimer(hWnd, 1, 100, NULL);
break;
case WM_TIMER:
switch (wParam)
{
case 1:
KillTimer(hWnd, 1);
RemoteDlgRefresh(hWnd, r);
SetTimer(hWnd, 1, 100, NULL);
break;
}
break;
case WM_COMMAND:
switch (wParam)
{
case R_LOCAL:
if (IsChecked(hWnd, R_LOCAL) == false)
{
SetTextA(hWnd, C_HOSTNAME, "");
RemoteDlgRefresh(hWnd, r);
FocusEx(hWnd, C_HOSTNAME);
}
else
{
SetTextA(hWnd, C_HOSTNAME, "localhost");
RemoteDlgRefresh(hWnd, r);
Focus(hWnd, IDOK);
}
break;
case IDCANCEL:
Close(hWnd);
break;
case IDOK:
RemoteDlgOnOk(hWnd, r);
break;
case B_ABOUT:
c = NewCedar(NULL, NULL);
About(hWnd, c, _UU("PRODUCT_NAME_ELOGMGR"));
ReleaseCedar(c);
}
switch (LOWORD(wParam))
{
case R_LOCAL:
case C_HOSTNAME:
RemoteDlgRefresh(hWnd, r);
break;
}
break;
case WM_CLOSE:
FreeCandidateList(r->CandidateList);
EndDialog(hWnd, false);
break;
}
return 0;
}
// Remote connection dialog
char *EmRemoteDlg()
{
WINUI_REMOTE r;
Zero(&r, sizeof(r));
r.RegKeyName = EM_REG_KEY;
r.Caption = _UU("EM_TITLE");
r.Title = _UU("EM_REMOTE_TITLE");
r.Icon = ICO_USER_ADMIN;
r.DefaultHostname = NULL;
if (Dialog(NULL, D_EM_REMOTE, EmRemoteDlgProc, &r) == false)
{
return NULL;
}
return r.Hostname;
}
// Start the EtherLogger Manager
void EMExec()
{
char *host;
char *ret;
bool cancel_now = false;
TOKEN_LIST *t;
UINT port = EL_ADMIN_PORT;
InitWinUi(_UU("EM_TITLE"), _SS("DEFAULT_FONT"), _II("DEFAULT_FONT_SIZE"));
while (true)
{
ret = EmRemoteDlg();
if (ret != NULL)
{
t = ParseToken(ret, ":");
if (t->NumTokens == 1 || t->NumTokens == 2)
{
RPC *rpc = NULL;
bool ok = false;
UINT ret;
host = t->Token[0];
if (t->NumTokens == 2)
{
port = ToInt(t->Token[1]);
}
else
{
port = EL_ADMIN_PORT;
}
// Try without a password first
ret = EcConnect(host, port, "", &rpc);
RETRY:
if (ret != ERR_NO_ERROR && ret != ERR_AUTH_FAILED)
{
// Connection failed
CALL(NULL, ret);
}
else
{
if (ret == ERR_NO_ERROR)
{
// Successful connection
ok = true;
}
else
{
// Password required
char *pass = SmPassword(NULL, host);
if (pass == NULL)
{
// Cancel
cancel_now = true;
}
else
{
// Retry
ret = EcConnect(host, port, pass, &rpc);
Free(pass);
if (ret == ERR_NO_ERROR)
{
ok = true;
}
else
{
goto RETRY;
}
}
}
}
if (ok)
{
// Main screen
EMMain(rpc);
// Disconnect
EcDisconnect(rpc);
cancel_now = true;
}
FreeToken(t);
}
Free(ret);
}
else
{
cancel_now = true;
}
if (cancel_now)
{
break;
}
}
FreeWinUi();
}
#endif // WIN32