Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

637 lines
20 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #include "sautil.h"
  4. #include "resource.h"
  5. #include "fwpages.h"
  6. #include <stddef.h>
  7. #include <commdlg.h>
  8. #define DEFAULT_FIREWALL_LOGFILE_SIZE 4096
  9. #define DEFAULT_FIREWALL_LOGFILE_PATH TEXT("\\pfirewall.log")
  10. extern LVXDRAWINFO*
  11. SasLvxCallback(
  12. HWND hwndLv,
  13. DWORD dwItem );
  14. static DWORD g_adwFirewallLoggingHelp[] =
  15. {
  16. CID_FL_CB_LogDroppedInbound, HID_FL_CB_LogDroppedInbound,
  17. CID_FL_CB_LogOutboundConnections, HID_FL_CB_LogOutboundConnections,
  18. CID_FL_EB_Filename, HID_FL_EB_Filename,
  19. CID_FL_PB_Browse, HID_FL_PB_Browse,
  20. CID_FL_EB_Filesize, HID_FL_EB_Filesize,
  21. CID_FL_PB_RestoreDefaults, HID_FL_PB_RestoreDefaults,
  22. 0, 0
  23. };
  24. static DWORD g_adwICMPHelp[] =
  25. {
  26. CID_IC_LV_Settings, HID_IC_LV_Settings,
  27. CID_IC_ST_Description, HID_IC_ST_Description,
  28. 0, 0
  29. };
  30. typedef struct tagICMPEntry
  31. {
  32. UINT uiStringID;
  33. UINT uiDescID;
  34. size_t Offset;
  35. } ICMPEntry;
  36. static ICMPEntry g_ICMPEntries[] =
  37. {
  38. {SID_ICMP_IECHO, SID_ICMP_IECHO_DESC, offsetof(HNET_FW_ICMP_SETTINGS, fAllowInboundEchoRequest)},
  39. {SID_ICMP_ITIME, SID_ICMP_ITIME_DESC, offsetof(HNET_FW_ICMP_SETTINGS, fAllowInboundTimestampRequest)},
  40. {SID_ICMP_IMASK, SID_ICMP_IMASK_DESC, offsetof(HNET_FW_ICMP_SETTINGS, fAllowInboundMaskRequest)},
  41. {SID_ICMP_IROUT, SID_ICMP_IROUT_DESC, offsetof(HNET_FW_ICMP_SETTINGS, fAllowInboundRouterRequest)},
  42. {SID_ICMP_ODEST, SID_ICMP_ODEST_DESC, offsetof(HNET_FW_ICMP_SETTINGS, fAllowOutboundDestinationUnreachable)},
  43. {SID_ICMP_OQNCH, SID_ICMP_OQNCH_DESC, offsetof(HNET_FW_ICMP_SETTINGS, fAllowOutboundSourceQuench)},
  44. {SID_ICMP_OPRAM, SID_ICMP_OPRAM_DESC, offsetof(HNET_FW_ICMP_SETTINGS, fAllowOutboundParameterProblem)},
  45. {SID_ICMP_OTIME, SID_ICMP_OTIME_DESC, offsetof(HNET_FW_ICMP_SETTINGS, fAllowOutboundTimeExceeded)},
  46. {SID_ICMP_XRDRT, SID_ICMP_XRDRT_DESC, offsetof(HNET_FW_ICMP_SETTINGS, fAllowRedirect)},
  47. {0, 0},
  48. };
  49. HRESULT CFirewallLoggingDialog_GetDefaultLogfilePath(LPTSTR* ppszLogFilePath);
  50. HRESULT CFirewallLoggingDialog_RestoreDefaults(HWND hwnd);
  51. HRESULT CFirewallLoggingDialog_Apply(CFirewallLoggingDialog* pThis, HWND hWindow);
  52. HRESULT CFirewallLoggingDialog_BrowseForLogfileName(HWND hWindow);
  53. HRESULT CICMPSettingsDialog_Apply(CICMPSettingsDialog* pThis, HWND hWindow);
  54. HRESULT CICMPSettingsDialog_ShowDescriptionText(HWND hwnd, INT nIndex);
  55. INT_PTR CALLBACK CFirewallLoggingDialog_StaticDlgProc(
  56. HWND hwnd,
  57. UINT unMsg,
  58. WPARAM wparam,
  59. LPARAM lparam )
  60. // Called to handle messages for the 'Firewall Logging' page.
  61. //
  62. {
  63. HRESULT hr = S_OK;
  64. switch (unMsg)
  65. {
  66. case WM_INITDIALOG:
  67. {
  68. PROPSHEETPAGE* pPropertySheetPage = (PROPSHEETPAGE*) lparam;
  69. CFirewallLoggingDialog* pFirewallLoggingDialog = (CFirewallLoggingDialog*) pPropertySheetPage->lParam;
  70. HNET_FW_LOGGING_SETTINGS* pSettings = pFirewallLoggingDialog->pSettings;
  71. SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) pFirewallLoggingDialog);
  72. // Ignore if this fails, we're better off without it than killing the whole page
  73. CreateUpDownControl(WS_CHILD | WS_VISIBLE | WS_BORDER | UDS_SETBUDDYINT
  74. | UDS_ALIGNRIGHT | UDS_NOTHOUSANDS | UDS_ARROWKEYS, 0, 0, 0, 0, hwnd, -1, g_hinstDll, GetDlgItem(hwnd, CID_FL_EB_Filesize), UD_MAXVAL, 0, 0);
  75. if(NULL != pSettings)
  76. {
  77. SetDlgItemText(hwnd, CID_FL_EB_Filename, pSettings->pszwPath);
  78. SetDlgItemInt(hwnd, CID_FL_EB_Filesize, (UINT) (pSettings->ulMaxFileSize / 1024), FALSE); // REVIEW safe cast?
  79. CheckDlgButton(hwnd, CID_FL_CB_LogOutboundConnections, pSettings->fLogConnections ? BST_CHECKED : BST_UNCHECKED);
  80. CheckDlgButton(hwnd, CID_FL_CB_LogDroppedInbound, pSettings->fLogDroppedPackets ? BST_CHECKED : BST_UNCHECKED);
  81. }
  82. else
  83. {
  84. CFirewallLoggingDialog_RestoreDefaults(hwnd);
  85. }
  86. return TRUE;
  87. }
  88. case WM_HELP:
  89. case WM_CONTEXTMENU:
  90. {
  91. ContextHelp(g_adwFirewallLoggingHelp, hwnd, unMsg, wparam, lparam);
  92. break;
  93. }
  94. case WM_COMMAND:
  95. {
  96. switch(LOWORD(wparam))
  97. {
  98. case CID_FL_PB_Browse:
  99. CFirewallLoggingDialog_BrowseForLogfileName(hwnd);
  100. break;
  101. case CID_FL_PB_RestoreDefaults:
  102. CFirewallLoggingDialog_RestoreDefaults(hwnd);
  103. break;
  104. }
  105. break;
  106. }
  107. case WM_NOTIFY:
  108. {
  109. switch (((NMHDR*)lparam)->code)
  110. {
  111. case PSN_KILLACTIVE:
  112. {
  113. BOOL bTranslated;
  114. UINT uiLogFileSize = GetDlgItemInt(hwnd, CID_FL_EB_Filesize, &bTranslated, FALSE);
  115. if(TRUE == bTranslated)
  116. {
  117. if(UD_MAXVAL < uiLogFileSize || 1 > uiLogFileSize)
  118. {
  119. MsgDlg(hwnd, SID_FwbInvalidSize, NULL);
  120. hr = E_UNEXPECTED;
  121. }
  122. }
  123. else
  124. {
  125. MsgDlg(hwnd, SID_FwbInvalidSize, NULL);
  126. hr = E_FAIL;
  127. }
  128. if(SUCCEEDED(hr))
  129. {
  130. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_NOERROR);
  131. }
  132. else
  133. {
  134. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID);
  135. }
  136. return TRUE;
  137. }
  138. case PSN_APPLY:
  139. {
  140. CFirewallLoggingDialog* pFirewallLoggingDialog;
  141. pFirewallLoggingDialog = (CFirewallLoggingDialog*) GetWindowLongPtr(hwnd, DWLP_USER);
  142. hr = CFirewallLoggingDialog_Apply(pFirewallLoggingDialog, hwnd);
  143. if(SUCCEEDED(hr))
  144. {
  145. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_NOERROR);
  146. }
  147. else
  148. {
  149. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID);
  150. }
  151. return TRUE;
  152. }
  153. }
  154. break;
  155. }
  156. }
  157. return FALSE;
  158. }
  159. HRESULT CFirewallLoggingDialog_RestoreDefaults(HWND hwnd)
  160. {
  161. HRESULT hr;
  162. LPTSTR pszLogFilePath;
  163. hr = CFirewallLoggingDialog_GetDefaultLogfilePath(&pszLogFilePath);
  164. if(SUCCEEDED(hr))
  165. {
  166. SetDlgItemText(hwnd, CID_FL_EB_Filename, pszLogFilePath);
  167. CoTaskMemFree(pszLogFilePath);
  168. }
  169. SetDlgItemInt(hwnd, CID_FL_EB_Filesize, DEFAULT_FIREWALL_LOGFILE_SIZE, FALSE);
  170. CheckDlgButton(hwnd, CID_FL_CB_LogOutboundConnections, BST_UNCHECKED);
  171. CheckDlgButton(hwnd, CID_FL_CB_LogDroppedInbound, BST_UNCHECKED);
  172. return hr;
  173. }
  174. HRESULT CFirewallLoggingDialog_Init(CFirewallLoggingDialog* pThis, IHNetCfgMgr* pHomenetConfigManager)
  175. {
  176. HRESULT hr;
  177. hr = pHomenetConfigManager->QueryInterface (IID_IHNetFirewallSettings,
  178. (void**)&pThis->pFirewallSettings);
  179. if(SUCCEEDED(hr))
  180. {
  181. hr = pThis->pFirewallSettings->GetFirewallLoggingSettings (&pThis->pSettings);
  182. if(HRESULT_FROM_WIN32(ERROR_OBJECT_NOT_FOUND) == hr)
  183. {
  184. ASSERT(NULL == pThis->pSettings);
  185. hr = S_OK;
  186. }
  187. if(FAILED(hr))
  188. {
  189. pThis->pFirewallSettings->Release();
  190. pThis->pFirewallSettings = NULL;
  191. }
  192. }
  193. return hr;
  194. }
  195. HRESULT CFirewallLoggingDialog_FinalRelease(CFirewallLoggingDialog* pThis)
  196. {
  197. pThis->pFirewallSettings->Release();
  198. if(NULL != pThis->pSettings)
  199. {
  200. if(NULL != pThis->pSettings->pszwPath)
  201. {
  202. CoTaskMemFree(pThis->pSettings->pszwPath);
  203. }
  204. }
  205. return S_OK;
  206. }
  207. HRESULT CFirewallLoggingDialog_GetDefaultLogfilePath(LPTSTR* ppszLogfilePath)
  208. {
  209. HRESULT hr = S_OK;
  210. LPTSTR pszAppendPath = DEFAULT_FIREWALL_LOGFILE_PATH;
  211. LPTSTR pszLogfilePath;
  212. UINT uiPathLength, uiLength;
  213. ASSERT(NULL != ppszLogfilePath);
  214. uiPathLength = GetWindowsDirectory(NULL, 0);
  215. if(0 != uiPathLength)
  216. {
  217. uiPathLength += lstrlen(pszAppendPath) + 1;
  218. pszLogfilePath = (LPTSTR) CoTaskMemAlloc((ULONG) (uiPathLength * sizeof(TCHAR)));
  219. if(NULL != pszLogfilePath)
  220. {
  221. // Whistler bug 224074 use only lstrcpyn's to prevent maliciousness
  222. //
  223. uiLength = GetWindowsDirectory(pszLogfilePath, uiPathLength);
  224. if(0 != uiLength)
  225. {
  226. // REVIEW if the size of the windir somehow changes then we have problems, but this can't happen right?
  227. //
  228. lstrcpyn(
  229. pszLogfilePath + uiLength,
  230. TEXT('\\') == pszLogfilePath[uiLength - 1] ?
  231. pszAppendPath + 1 : pszAppendPath,
  232. uiPathLength - uiLength);
  233. *ppszLogfilePath = pszLogfilePath;
  234. }
  235. else
  236. {
  237. hr = E_FAIL;
  238. }
  239. if(FAILED(hr))
  240. {
  241. CoTaskMemFree(pszLogfilePath);
  242. }
  243. }
  244. else
  245. {
  246. hr = E_OUTOFMEMORY;
  247. }
  248. }
  249. else
  250. {
  251. hr = E_FAIL;
  252. }
  253. return hr;
  254. }
  255. HRESULT CFirewallLoggingDialog_Apply(CFirewallLoggingDialog* pThis, HWND hWindow)
  256. {
  257. HRESULT hr = S_OK;
  258. HNET_FW_LOGGING_SETTINGS NewSettings;
  259. BOOL bTranslated;
  260. UINT uiLogFileSize;
  261. UINT uiSizeNeeded;
  262. NewSettings.fLogDroppedPackets = BST_CHECKED == IsDlgButtonChecked(hWindow, CID_FL_CB_LogDroppedInbound);
  263. NewSettings.fLogConnections = BST_CHECKED == IsDlgButtonChecked(hWindow, CID_FL_CB_LogOutboundConnections);
  264. NewSettings.pszwPath = NULL;
  265. if(SUCCEEDED(hr))
  266. {
  267. uiSizeNeeded = Edit_GetTextLength(GetDlgItem(hWindow, CID_FL_EB_Filename)) + 1;
  268. if(0 != uiSizeNeeded)
  269. {
  270. NewSettings.pszwPath = (LPWSTR) CoTaskMemAlloc((ULONG) (uiSizeNeeded * sizeof(TCHAR)));
  271. if(NULL != NewSettings.pszwPath)
  272. {
  273. uiSizeNeeded = GetDlgItemText(hWindow, CID_FL_EB_Filename, NewSettings.pszwPath, uiSizeNeeded);
  274. if(0 == uiSizeNeeded)
  275. {
  276. hr = E_FAIL;
  277. }
  278. }
  279. else
  280. {
  281. hr = E_OUTOFMEMORY;
  282. }
  283. }
  284. else
  285. {
  286. hr = E_UNEXPECTED; // invalid param, empty filename
  287. }
  288. }
  289. if(SUCCEEDED(hr))
  290. {
  291. uiLogFileSize = GetDlgItemInt(hWindow, CID_FL_EB_Filesize, &bTranslated, FALSE);
  292. if(TRUE == bTranslated)
  293. {
  294. NewSettings.ulMaxFileSize = 1024 * (ULONG) uiLogFileSize;
  295. }
  296. else
  297. {
  298. hr = E_UNEXPECTED; // invalid param
  299. }
  300. }
  301. if(SUCCEEDED(hr))
  302. {
  303. BOOL bDirty = TRUE;
  304. if(NULL != pThis->pSettings) // we may not have gotten one on GetFirewallLoggingSettings
  305. {
  306. bDirty = FALSE;
  307. bDirty |= NewSettings.fLogDroppedPackets != pThis->pSettings->fLogDroppedPackets;
  308. bDirty |= NewSettings.fLogConnections != pThis->pSettings->fLogConnections;
  309. bDirty |= NewSettings.ulMaxFileSize != pThis->pSettings->ulMaxFileSize;
  310. bDirty |= 0 != lstrcmp(NewSettings.pszwPath, pThis->pSettings->pszwPath);
  311. }
  312. if(TRUE == bDirty)
  313. {
  314. hr = pThis->pFirewallSettings->SetFirewallLoggingSettings (&NewSettings);
  315. }
  316. }
  317. if(NULL != NewSettings.pszwPath)
  318. {
  319. CoTaskMemFree(NewSettings.pszwPath);
  320. }
  321. return hr;
  322. }
  323. HRESULT CFirewallLoggingDialog_BrowseForLogfileName(HWND hWindow)
  324. {
  325. HRESULT hr = S_OK;
  326. OPENFILENAME ofn;
  327. TCHAR* pszFilterDesc;
  328. TCHAR* pszFilter;
  329. TCHAR* pszDefExt;
  330. TCHAR* pszTitle;
  331. TCHAR szBuf[ MAX_PATH + 1 ] = L"";
  332. TCHAR szDir[ MAX_PATH + 1] = L"";
  333. // Fill in FileOpen dialog parameter buffer.
  334. //
  335. // if any of these fail just let them be null
  336. pszFilterDesc = PszFromId( g_hinstDll, SID_FwbFilterDesc );
  337. pszTitle = PszFromId( g_hinstDll, SID_FwbTitle );
  338. pszDefExt = PszFromId( g_hinstDll, SID_FwbDefExt );
  339. // if this fails we will have a null path, so the open dialog should open at the root
  340. if(0 != GetDlgItemText(hWindow, CID_FL_EB_Filename, szDir, sizeof(szDir) / sizeof(TCHAR)))
  341. {
  342. // lose the file name
  343. LPWSTR pszLastSlash = wcsrchr(szDir, L'\\');
  344. if(NULL != pszLastSlash)
  345. {
  346. *pszLastSlash = L'\0';
  347. }
  348. }
  349. ZeroMemory(&ofn, sizeof(ofn));
  350. ofn.lStructSize = sizeof(ofn);
  351. ofn.hwndOwner = GetParent( hWindow );
  352. ofn.hInstance = g_hinstDll;
  353. ofn.lpstrFilter = pszFilterDesc;
  354. ofn.nFilterIndex = 1;
  355. ofn.lpstrFile = szBuf;
  356. ofn.nMaxFile = MAX_PATH;
  357. ofn.lpstrInitialDir = szDir;
  358. ofn.lpstrTitle = pszTitle;
  359. ofn.lpstrDefExt = pszDefExt;
  360. ofn.Flags = 0;
  361. if (GetOpenFileName (&ofn))
  362. {
  363. SetWindowText( GetDlgItem(hWindow, CID_FL_EB_Filename), ofn.lpstrFile );
  364. }
  365. Free0(pszTitle);
  366. Free0(pszDefExt);
  367. Free0(pszFilterDesc);
  368. return S_OK;
  369. }
  370. INT_PTR CALLBACK CICMPSettingsDialog_StaticDlgProc(
  371. HWND hwnd,
  372. UINT unMsg,
  373. WPARAM wparam,
  374. LPARAM lparam )
  375. // Called to handle messages for the 'ICMP' page.
  376. //
  377. {
  378. HRESULT hr;
  379. // Give the extended list-control a chance to look at all messages first.
  380. //
  381. if (ListView_OwnerHandler(hwnd, unMsg, wparam, lparam, SasLvxCallback))
  382. {
  383. return TRUE;
  384. }
  385. switch (unMsg)
  386. {
  387. case WM_INITDIALOG:
  388. {
  389. UINT i = 0;
  390. UINT uiEntry = 0;
  391. LVITEM lvi;
  392. HWND hListView;
  393. PROPSHEETPAGE* pPropertySheetPage = (PROPSHEETPAGE*) lparam;
  394. CICMPSettingsDialog* pICMPSettingsDialog = (CICMPSettingsDialog*) pPropertySheetPage->lParam;
  395. HNET_FW_ICMP_SETTINGS* pSettings = pICMPSettingsDialog->pSettings;
  396. ASSERT(NULL != pSettings);
  397. SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) pICMPSettingsDialog);
  398. hListView = GetDlgItem(hwnd, CID_IC_LV_Settings);
  399. ASSERT(NULL != hListView);
  400. ListView_InstallChecks(hListView, g_hinstDll);
  401. ListView_InsertSingleAutoWidthColumn(hListView);
  402. while(0 != g_ICMPEntries[uiEntry].uiStringID)
  403. {
  404. LPTSTR pszText = PszFromId(g_hinstDll, g_ICMPEntries[uiEntry].uiStringID);
  405. if(NULL != pszText)
  406. {
  407. ZeroMemory(&lvi, sizeof(lvi));
  408. lvi.mask = LVIF_TEXT | LVIF_PARAM;
  409. lvi.iItem = i + 1; // add to end
  410. lvi.lParam = (LPARAM) g_ICMPEntries[uiEntry].Offset;
  411. lvi.pszText = pszText;
  412. lvi.cchTextMax = lstrlen(pszText) + 1;
  413. i = ListView_InsertItem(hListView, &lvi);
  414. if (i != -1)
  415. {
  416. ListView_SetCheck(hListView, i, (BOOLEAN)*((BYTE*)pSettings + g_ICMPEntries[uiEntry].Offset)); // REVIEW 64bit safe?
  417. }
  418. Free(pszText);
  419. }
  420. uiEntry++;
  421. }
  422. ListView_SetItemState(hListView, 0, LVIS_SELECTED, LVIS_SELECTED);
  423. CICMPSettingsDialog_ShowDescriptionText(hwnd, 0);
  424. return TRUE;
  425. }
  426. case WM_HELP:
  427. case WM_CONTEXTMENU:
  428. {
  429. ContextHelp(g_adwICMPHelp, hwnd, unMsg, wparam, lparam);
  430. break;
  431. }
  432. case WM_COMMAND:
  433. {
  434. break;
  435. }
  436. case WM_NOTIFY:
  437. {
  438. switch (((NMHDR*)lparam)->code)
  439. {
  440. case PSN_APPLY:
  441. {
  442. CICMPSettingsDialog* pICMPSettingsDialog;
  443. pICMPSettingsDialog = (CICMPSettingsDialog*) GetWindowLongPtr(hwnd, DWLP_USER);
  444. hr = CICMPSettingsDialog_Apply(pICMPSettingsDialog, hwnd);
  445. if(SUCCEEDED(hr))
  446. {
  447. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_NOERROR);
  448. }
  449. else
  450. {
  451. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, PSNRET_INVALID);
  452. }
  453. return TRUE;
  454. }
  455. case LVXN_SETCHECK:
  456. {
  457. return TRUE;
  458. }
  459. case LVN_ITEMCHANGED:
  460. {
  461. INT nSelectedItem;
  462. LPNMLISTVIEW ListViewInfo = (LPNMLISTVIEW) lparam;
  463. if(-1 != ListViewInfo->iItem && LVIS_SELECTED & ListViewInfo->uNewState)
  464. {
  465. CICMPSettingsDialog_ShowDescriptionText(hwnd, ListViewInfo->iItem);
  466. }
  467. return TRUE;
  468. }
  469. }
  470. break;
  471. }
  472. }
  473. return FALSE;
  474. }
  475. HRESULT CICMPSettingsDialog_Init(CICMPSettingsDialog* pThis, IHNetConnection* pHomenetConnection)
  476. {
  477. HRESULT hr;
  478. pThis->pConnection = pHomenetConnection;
  479. pHomenetConnection->AddRef();
  480. hr = pHomenetConnection->GetIcmpSettings (&pThis->pSettings);
  481. if(FAILED(hr))
  482. {
  483. pHomenetConnection->Release();
  484. }
  485. return hr;
  486. }
  487. HRESULT CICMPSettingsDialog_FinalRelease(CICMPSettingsDialog* pThis)
  488. {
  489. ASSERT(pThis->pConnection);
  490. pThis->pConnection->Release();
  491. ASSERT(pThis->pSettings);
  492. CoTaskMemFree(pThis->pSettings);
  493. return S_OK;
  494. }
  495. HRESULT CICMPSettingsDialog_Apply(CICMPSettingsDialog* pThis, HWND hWindow)
  496. {
  497. HRESULT hr = S_OK;
  498. HNET_FW_ICMP_SETTINGS NewSettings;
  499. BOOL bDirty = FALSE;
  500. HWND hListView;
  501. LVITEM lvi;
  502. int nItemCount;
  503. hListView = GetDlgItem(hWindow, CID_IC_LV_Settings);
  504. ASSERT(NULL != hListView);
  505. ZeroMemory(&lvi, sizeof(lvi));
  506. lvi.mask = LVIF_PARAM;
  507. nItemCount = ListView_GetItemCount(hListView);
  508. while(0 < nItemCount--)
  509. {
  510. BOOLEAN bChecked = (BOOLEAN) ListView_GetCheck(hListView, nItemCount); // REVIEW can this error?
  511. lvi.iItem = nItemCount;
  512. if(TRUE == ListView_GetItem(hListView, &lvi))
  513. {
  514. (BOOLEAN)*((BYTE*)&NewSettings + lvi.lParam) = bChecked;
  515. if(bChecked != (BOOLEAN)*((BYTE*)(pThis->pSettings) + lvi.lParam)) // REVIEW 64bit safe?
  516. {
  517. bDirty = TRUE;
  518. }
  519. }
  520. }
  521. if(bDirty)
  522. {
  523. hr = pThis->pConnection->SetIcmpSettings (&NewSettings);
  524. }
  525. return hr;
  526. }
  527. HRESULT CICMPSettingsDialog_ShowDescriptionText(HWND hwnd, INT nIndex)
  528. {
  529. LPWSTR pszDescription = PszFromId(g_hinstDll, g_ICMPEntries[nIndex].uiDescID);
  530. if(NULL != pszDescription)
  531. {
  532. SetDlgItemText(hwnd, CID_IC_ST_Description, pszDescription);
  533. Free(pszDescription);
  534. }
  535. return S_OK;
  536. }