windows-nt/Source/XPSP1/NT/net/homenet/config/dll/fwpages.cpp
2020-09-26 16:20:57 +08:00

638 lines
19 KiB
C++

#include "pch.h"
#pragma hdrstop
#include "sautil.h"
#include "resource.h"
#include "fwpages.h"
#include <stddef.h>
#include <commdlg.h>
#define DEFAULT_FIREWALL_LOGFILE_SIZE 4096
#define DEFAULT_FIREWALL_LOGFILE_PATH TEXT("\\pfirewall.log")
extern LVXDRAWINFO*
SasLvxCallback(
HWND hwndLv,
DWORD dwItem );
static DWORD g_adwFirewallLoggingHelp[] =
{
CID_FL_CB_LogDroppedInbound, HID_FL_CB_LogDroppedInbound,
CID_FL_CB_LogOutboundConnections, HID_FL_CB_LogOutboundConnections,
CID_FL_EB_Filename, HID_FL_EB_Filename,
CID_FL_PB_Browse, HID_FL_PB_Browse,
CID_FL_EB_Filesize, HID_FL_EB_Filesize,
CID_FL_PB_RestoreDefaults, HID_FL_PB_RestoreDefaults,
0, 0
};
static DWORD g_adwICMPHelp[] =
{
CID_IC_LV_Settings, HID_IC_LV_Settings,
CID_IC_ST_Description, HID_IC_ST_Description,
0, 0
};
typedef struct tagICMPEntry
{
UINT uiStringID;
UINT uiDescID;
size_t Offset;
} ICMPEntry;
static ICMPEntry g_ICMPEntries[] =
{
{SID_ICMP_IECHO, SID_ICMP_IECHO_DESC, offsetof(HNET_FW_ICMP_SETTINGS, fAllowInboundEchoRequest)},
{SID_ICMP_ITIME, SID_ICMP_ITIME_DESC, offsetof(HNET_FW_ICMP_SETTINGS, fAllowInboundTimestampRequest)},
{SID_ICMP_IMASK, SID_ICMP_IMASK_DESC, offsetof(HNET_FW_ICMP_SETTINGS, fAllowInboundMaskRequest)},
{SID_ICMP_IROUT, SID_ICMP_IROUT_DESC, offsetof(HNET_FW_ICMP_SETTINGS, fAllowInboundRouterRequest)},
{SID_ICMP_ODEST, SID_ICMP_ODEST_DESC, offsetof(HNET_FW_ICMP_SETTINGS, fAllowOutboundDestinationUnreachable)},
{SID_ICMP_OQNCH, SID_ICMP_OQNCH_DESC, offsetof(HNET_FW_ICMP_SETTINGS, fAllowOutboundSourceQuench)},
{SID_ICMP_OPRAM, SID_ICMP_OPRAM_DESC, offsetof(HNET_FW_ICMP_SETTINGS, fAllowOutboundParameterProblem)},
{SID_ICMP_OTIME, SID_ICMP_OTIME_DESC, offsetof(HNET_FW_ICMP_SETTINGS, fAllowOutboundTimeExceeded)},
{SID_ICMP_XRDRT, SID_ICMP_XRDRT_DESC, offsetof(HNET_FW_ICMP_SETTINGS, fAllowRedirect)},
{0, 0},
};
HRESULT CFirewallLoggingDialog_GetDefaultLogfilePath(LPTSTR* ppszLogFilePath);
HRESULT CFirewallLoggingDialog_RestoreDefaults(HWND hwnd);
HRESULT CFirewallLoggingDialog_Apply(CFirewallLoggingDialog* pThis, HWND hWindow);
HRESULT CFirewallLoggingDialog_BrowseForLogfileName(HWND hWindow);
HRESULT CICMPSettingsDialog_Apply(CICMPSettingsDialog* pThis, HWND hWindow);
HRESULT CICMPSettingsDialog_ShowDescriptionText(HWND hwnd, INT nIndex);
INT_PTR CALLBACK CFirewallLoggingDialog_StaticDlgProc(
HWND hwnd,
UINT unMsg,
WPARAM wparam,
LPARAM lparam )
// Called to handle messages for the 'Firewall Logging' page.
//
{
HRESULT hr = S_OK;
switch (unMsg)
{
case WM_INITDIALOG:
{
PROPSHEETPAGE* pPropertySheetPage = (PROPSHEETPAGE*) lparam;
CFirewallLoggingDialog* pFirewallLoggingDialog = (CFirewallLoggingDialog*) pPropertySheetPage->lParam;
HNET_FW_LOGGING_SETTINGS* pSettings = pFirewallLoggingDialog->pSettings;
SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) pFirewallLoggingDialog);
// Ignore if this fails, we're better off without it than killing the whole page
CreateUpDownControl(WS_CHILD | WS_VISIBLE | WS_BORDER | UDS_SETBUDDYINT
| UDS_ALIGNRIGHT | UDS_NOTHOUSANDS | UDS_ARROWKEYS, 0, 0, 0, 0, hwnd, -1, g_hinstDll, GetDlgItem(hwnd, CID_FL_EB_Filesize), UD_MAXVAL, 0, 0);
if(NULL != pSettings)
{
SetDlgItemText(hwnd, CID_FL_EB_Filename, pSettings->pszwPath);
SetDlgItemInt(hwnd, CID_FL_EB_Filesize, (UINT) (pSettings->ulMaxFileSize / 1024), FALSE); // REVIEW safe cast?
CheckDlgButton(hwnd, CID_FL_CB_LogOutboundConnections, pSettings->fLogConnections ? BST_CHECKED : BST_UNCHECKED);
CheckDlgButton(hwnd, CID_FL_CB_LogDroppedInbound, pSettings->fLogDroppedPackets ? BST_CHECKED : BST_UNCHECKED);
}
else
{
CFirewallLoggingDialog_RestoreDefaults(hwnd);
}
return TRUE;
}
case WM_HELP:
case WM_CONTEXTMENU:
{
ContextHelp(g_adwFirewallLoggingHelp, hwnd, unMsg, wparam, lparam);
break;
}
case WM_COMMAND:
{
switch(LOWORD(wparam))
{
case CID_FL_PB_Browse:
CFirewallLoggingDialog_BrowseForLogfileName(hwnd);
break;
case CID_FL_PB_RestoreDefaults:
CFirewallLoggingDialog_RestoreDefaults(hwnd);
break;
}
break;
}
case WM_NOTIFY:
{
switch (((NMHDR*)lparam)->code)
{
case PSN_KILLACTIVE:
{
BOOL bTranslated;
UINT uiLogFileSize = GetDlgItemInt(hwnd, CID_FL_EB_Filesize, &bTranslated, FALSE);
if(TRUE == bTranslated)
{
if(UD_MAXVAL < uiLogFileSize || 1 > uiLogFileSize)
{
MsgDlg(hwnd, SID_FwbInvalidSize, NULL);
hr = E_UNEXPECTED;
}
}
else
{
MsgDlg(hwnd, SID_FwbInvalidSize, NULL);
hr = E_FAIL;
}
if(SUCCEEDED(hr))
{
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_NOERROR);
}
else
{
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID);
}
return TRUE;
}
case PSN_APPLY:
{
CFirewallLoggingDialog* pFirewallLoggingDialog;
pFirewallLoggingDialog = (CFirewallLoggingDialog*) GetWindowLongPtr(hwnd, DWLP_USER);
hr = CFirewallLoggingDialog_Apply(pFirewallLoggingDialog, hwnd);
if(SUCCEEDED(hr))
{
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_NOERROR);
}
else
{
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID);
}
return TRUE;
}
}
break;
}
}
return FALSE;
}
HRESULT CFirewallLoggingDialog_RestoreDefaults(HWND hwnd)
{
HRESULT hr;
LPTSTR pszLogFilePath;
hr = CFirewallLoggingDialog_GetDefaultLogfilePath(&pszLogFilePath);
if(SUCCEEDED(hr))
{
SetDlgItemText(hwnd, CID_FL_EB_Filename, pszLogFilePath);
CoTaskMemFree(pszLogFilePath);
}
SetDlgItemInt(hwnd, CID_FL_EB_Filesize, DEFAULT_FIREWALL_LOGFILE_SIZE, FALSE);
CheckDlgButton(hwnd, CID_FL_CB_LogOutboundConnections, BST_UNCHECKED);
CheckDlgButton(hwnd, CID_FL_CB_LogDroppedInbound, BST_UNCHECKED);
return hr;
}
HRESULT CFirewallLoggingDialog_Init(CFirewallLoggingDialog* pThis, IHNetCfgMgr* pHomenetConfigManager)
{
HRESULT hr;
hr = pHomenetConfigManager->QueryInterface (IID_IHNetFirewallSettings,
(void**)&pThis->pFirewallSettings);
if(SUCCEEDED(hr))
{
hr = pThis->pFirewallSettings->GetFirewallLoggingSettings (&pThis->pSettings);
if(HRESULT_FROM_WIN32(ERROR_OBJECT_NOT_FOUND) == hr)
{
ASSERT(NULL == pThis->pSettings);
hr = S_OK;
}
if(FAILED(hr))
{
pThis->pFirewallSettings->Release();
pThis->pFirewallSettings = NULL;
}
}
return hr;
}
HRESULT CFirewallLoggingDialog_FinalRelease(CFirewallLoggingDialog* pThis)
{
pThis->pFirewallSettings->Release();
if(NULL != pThis->pSettings)
{
if(NULL != pThis->pSettings->pszwPath)
{
CoTaskMemFree(pThis->pSettings->pszwPath);
}
}
return S_OK;
}
HRESULT CFirewallLoggingDialog_GetDefaultLogfilePath(LPTSTR* ppszLogfilePath)
{
HRESULT hr = S_OK;
LPTSTR pszAppendPath = DEFAULT_FIREWALL_LOGFILE_PATH;
LPTSTR pszLogfilePath;
UINT uiPathLength, uiLength;
ASSERT(NULL != ppszLogfilePath);
uiPathLength = GetWindowsDirectory(NULL, 0);
if(0 != uiPathLength)
{
uiPathLength += lstrlen(pszAppendPath) + 1;
pszLogfilePath = (LPTSTR) CoTaskMemAlloc((ULONG) (uiPathLength * sizeof(TCHAR)));
if(NULL != pszLogfilePath)
{
// Whistler bug 224074 use only lstrcpyn's to prevent maliciousness
//
uiLength = GetWindowsDirectory(pszLogfilePath, uiPathLength);
if(0 != uiLength)
{
// REVIEW if the size of the windir somehow changes then we have problems, but this can't happen right?
//
lstrcpyn(
pszLogfilePath + uiLength,
TEXT('\\') == pszLogfilePath[uiLength - 1] ?
pszAppendPath + 1 : pszAppendPath,
uiPathLength - uiLength);
*ppszLogfilePath = pszLogfilePath;
}
else
{
hr = E_FAIL;
}
if(FAILED(hr))
{
CoTaskMemFree(pszLogfilePath);
}
}
else
{
hr = E_OUTOFMEMORY;
}
}
else
{
hr = E_FAIL;
}
return hr;
}
HRESULT CFirewallLoggingDialog_Apply(CFirewallLoggingDialog* pThis, HWND hWindow)
{
HRESULT hr = S_OK;
HNET_FW_LOGGING_SETTINGS NewSettings;
BOOL bTranslated;
UINT uiLogFileSize;
UINT uiSizeNeeded;
NewSettings.fLogDroppedPackets = BST_CHECKED == IsDlgButtonChecked(hWindow, CID_FL_CB_LogDroppedInbound);
NewSettings.fLogConnections = BST_CHECKED == IsDlgButtonChecked(hWindow, CID_FL_CB_LogOutboundConnections);
NewSettings.pszwPath = NULL;
if(SUCCEEDED(hr))
{
uiSizeNeeded = Edit_GetTextLength(GetDlgItem(hWindow, CID_FL_EB_Filename)) + 1;
if(0 != uiSizeNeeded)
{
NewSettings.pszwPath = (LPWSTR) CoTaskMemAlloc((ULONG) (uiSizeNeeded * sizeof(TCHAR)));
if(NULL != NewSettings.pszwPath)
{
uiSizeNeeded = GetDlgItemText(hWindow, CID_FL_EB_Filename, NewSettings.pszwPath, uiSizeNeeded);
if(0 == uiSizeNeeded)
{
hr = E_FAIL;
}
}
else
{
hr = E_OUTOFMEMORY;
}
}
else
{
hr = E_UNEXPECTED; // invalid param, empty filename
}
}
if(SUCCEEDED(hr))
{
uiLogFileSize = GetDlgItemInt(hWindow, CID_FL_EB_Filesize, &bTranslated, FALSE);
if(TRUE == bTranslated)
{
NewSettings.ulMaxFileSize = 1024 * (ULONG) uiLogFileSize;
}
else
{
hr = E_UNEXPECTED; // invalid param
}
}
if(SUCCEEDED(hr))
{
BOOL bDirty = TRUE;
if(NULL != pThis->pSettings) // we may not have gotten one on GetFirewallLoggingSettings
{
bDirty = FALSE;
bDirty |= NewSettings.fLogDroppedPackets != pThis->pSettings->fLogDroppedPackets;
bDirty |= NewSettings.fLogConnections != pThis->pSettings->fLogConnections;
bDirty |= NewSettings.ulMaxFileSize != pThis->pSettings->ulMaxFileSize;
bDirty |= 0 != lstrcmp(NewSettings.pszwPath, pThis->pSettings->pszwPath);
}
if(TRUE == bDirty)
{
hr = pThis->pFirewallSettings->SetFirewallLoggingSettings (&NewSettings);
}
}
if(NULL != NewSettings.pszwPath)
{
CoTaskMemFree(NewSettings.pszwPath);
}
return hr;
}
HRESULT CFirewallLoggingDialog_BrowseForLogfileName(HWND hWindow)
{
HRESULT hr = S_OK;
OPENFILENAME ofn;
TCHAR* pszFilterDesc;
TCHAR* pszFilter;
TCHAR* pszDefExt;
TCHAR* pszTitle;
TCHAR szBuf[ MAX_PATH + 1 ] = L"";
TCHAR szDir[ MAX_PATH + 1] = L"";
// Fill in FileOpen dialog parameter buffer.
//
// if any of these fail just let them be null
pszFilterDesc = PszFromId( g_hinstDll, SID_FwbFilterDesc );
pszTitle = PszFromId( g_hinstDll, SID_FwbTitle );
pszDefExt = PszFromId( g_hinstDll, SID_FwbDefExt );
// if this fails we will have a null path, so the open dialog should open at the root
if(0 != GetDlgItemText(hWindow, CID_FL_EB_Filename, szDir, sizeof(szDir) / sizeof(TCHAR)))
{
// lose the file name
LPWSTR pszLastSlash = wcsrchr(szDir, L'\\');
if(NULL != pszLastSlash)
{
*pszLastSlash = L'\0';
}
}
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = GetParent( hWindow );
ofn.hInstance = g_hinstDll;
ofn.lpstrFilter = pszFilterDesc;
ofn.nFilterIndex = 1;
ofn.lpstrFile = szBuf;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrInitialDir = szDir;
ofn.lpstrTitle = pszTitle;
ofn.lpstrDefExt = pszDefExt;
ofn.Flags = 0;
if (GetOpenFileName (&ofn))
{
SetWindowText( GetDlgItem(hWindow, CID_FL_EB_Filename), ofn.lpstrFile );
}
Free0(pszTitle);
Free0(pszDefExt);
Free0(pszFilterDesc);
return S_OK;
}
INT_PTR CALLBACK CICMPSettingsDialog_StaticDlgProc(
HWND hwnd,
UINT unMsg,
WPARAM wparam,
LPARAM lparam )
// Called to handle messages for the 'ICMP' page.
//
{
HRESULT hr;
// Give the extended list-control a chance to look at all messages first.
//
if (ListView_OwnerHandler(hwnd, unMsg, wparam, lparam, SasLvxCallback))
{
return TRUE;
}
switch (unMsg)
{
case WM_INITDIALOG:
{
UINT i = 0;
UINT uiEntry = 0;
LVITEM lvi;
HWND hListView;
PROPSHEETPAGE* pPropertySheetPage = (PROPSHEETPAGE*) lparam;
CICMPSettingsDialog* pICMPSettingsDialog = (CICMPSettingsDialog*) pPropertySheetPage->lParam;
HNET_FW_ICMP_SETTINGS* pSettings = pICMPSettingsDialog->pSettings;
ASSERT(NULL != pSettings);
SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) pICMPSettingsDialog);
hListView = GetDlgItem(hwnd, CID_IC_LV_Settings);
ASSERT(NULL != hListView);
ListView_InstallChecks(hListView, g_hinstDll);
ListView_InsertSingleAutoWidthColumn(hListView);
while(0 != g_ICMPEntries[uiEntry].uiStringID)
{
LPTSTR pszText = PszFromId(g_hinstDll, g_ICMPEntries[uiEntry].uiStringID);
if(NULL != pszText)
{
ZeroMemory(&lvi, sizeof(lvi));
lvi.mask = LVIF_TEXT | LVIF_PARAM;
lvi.iItem = i + 1; // add to end
lvi.lParam = (LPARAM) g_ICMPEntries[uiEntry].Offset;
lvi.pszText = pszText;
lvi.cchTextMax = lstrlen(pszText) + 1;
i = ListView_InsertItem(hListView, &lvi);
if (i != -1)
{
ListView_SetCheck(hListView, i, (BOOLEAN)*((BYTE*)pSettings + g_ICMPEntries[uiEntry].Offset)); // REVIEW 64bit safe?
}
Free(pszText);
}
uiEntry++;
}
ListView_SetItemState(hListView, 0, LVIS_SELECTED, LVIS_SELECTED);
CICMPSettingsDialog_ShowDescriptionText(hwnd, 0);
return TRUE;
}
case WM_HELP:
case WM_CONTEXTMENU:
{
ContextHelp(g_adwICMPHelp, hwnd, unMsg, wparam, lparam);
break;
}
case WM_COMMAND:
{
break;
}
case WM_NOTIFY:
{
switch (((NMHDR*)lparam)->code)
{
case PSN_APPLY:
{
CICMPSettingsDialog* pICMPSettingsDialog;
pICMPSettingsDialog = (CICMPSettingsDialog*) GetWindowLongPtr(hwnd, DWLP_USER);
hr = CICMPSettingsDialog_Apply(pICMPSettingsDialog, hwnd);
if(SUCCEEDED(hr))
{
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_NOERROR);
}
else
{
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID);
}
return TRUE;
}
case LVXN_SETCHECK:
{
return TRUE;
}
case LVN_ITEMCHANGED:
{
INT nSelectedItem;
LPNMLISTVIEW ListViewInfo = (LPNMLISTVIEW) lparam;
if(-1 != ListViewInfo->iItem && LVIS_SELECTED & ListViewInfo->uNewState)
{
CICMPSettingsDialog_ShowDescriptionText(hwnd, ListViewInfo->iItem);
}
return TRUE;
}
}
break;
}
}
return FALSE;
}
HRESULT CICMPSettingsDialog_Init(CICMPSettingsDialog* pThis, IHNetConnection* pHomenetConnection)
{
HRESULT hr;
pThis->pConnection = pHomenetConnection;
pHomenetConnection->AddRef();
hr = pHomenetConnection->GetIcmpSettings (&pThis->pSettings);
if(FAILED(hr))
{
pHomenetConnection->Release();
}
return hr;
}
HRESULT CICMPSettingsDialog_FinalRelease(CICMPSettingsDialog* pThis)
{
ASSERT(pThis->pConnection);
pThis->pConnection->Release();
ASSERT(pThis->pSettings);
CoTaskMemFree(pThis->pSettings);
return S_OK;
}
HRESULT CICMPSettingsDialog_Apply(CICMPSettingsDialog* pThis, HWND hWindow)
{
HRESULT hr = S_OK;
HNET_FW_ICMP_SETTINGS NewSettings;
BOOL bDirty = FALSE;
HWND hListView;
LVITEM lvi;
int nItemCount;
hListView = GetDlgItem(hWindow, CID_IC_LV_Settings);
ASSERT(NULL != hListView);
ZeroMemory(&lvi, sizeof(lvi));
lvi.mask = LVIF_PARAM;
nItemCount = ListView_GetItemCount(hListView);
while(0 < nItemCount--)
{
BOOLEAN bChecked = (BOOLEAN) ListView_GetCheck(hListView, nItemCount); // REVIEW can this error?
lvi.iItem = nItemCount;
if(TRUE == ListView_GetItem(hListView, &lvi))
{
(BOOLEAN)*((BYTE*)&NewSettings + lvi.lParam) = bChecked;
if(bChecked != (BOOLEAN)*((BYTE*)(pThis->pSettings) + lvi.lParam)) // REVIEW 64bit safe?
{
bDirty = TRUE;
}
}
}
if(bDirty)
{
hr = pThis->pConnection->SetIcmpSettings (&NewSettings);
}
return hr;
}
HRESULT CICMPSettingsDialog_ShowDescriptionText(HWND hwnd, INT nIndex)
{
LPWSTR pszDescription = PszFromId(g_hinstDll, g_ICMPEntries[nIndex].uiDescID);
if(NULL != pszDescription)
{
SetDlgItemText(hwnd, CID_IC_ST_Description, pszDescription);
Free(pszDescription);
}
return S_OK;
}