Source code of Windows XP (NT5)
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.

540 lines
16 KiB

  1. //-----------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: D L G I P S E C . C P P
  7. //
  8. // Contents: Implementation for CIpSecDialog
  9. //
  10. // Notes: CIpSecDialog is the pop-up dislogs for IPSEC from
  11. // options page
  12. //
  13. // Author: tongl 18 Jan, 1998
  14. //-----------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "tcpipobj.h"
  18. #include "ncstl.h"
  19. #include "ncui.h"
  20. #include "resource.h"
  21. #include "tcpconst.h"
  22. #include "tcpmacro.h"
  23. #include "tcputil.h"
  24. #include "dlgopt.h"
  25. #include "lmcons.h"
  26. #include "lmerr.h"
  27. #include "cpolstor.h"
  28. #include "ncbase.h"
  29. struct IPSEC_POLICY_INFO
  30. {
  31. WCHAR szPolicyName[MAX_PATH];
  32. WCHAR szPolicyDescription[MAX_PATH];
  33. GUID guidPolicyId;
  34. };
  35. //const WCHAR c_szDomainPolicyKey[] =
  36. // L"System\\CurrentControlSet\\Services\\PolicyAgent\\Policy\\GPTIPSECPolicy";
  37. //const WCHAR c_szDomainPolicyName[] = L"DSIPSECPolicyName";
  38. //
  39. // CIpSecDialog
  40. //
  41. CIpSecDialog::CIpSecDialog (CTcpOptionsPage * pOptionsPage,
  42. GLOBAL_INFO * pGlbDlg,
  43. const DWORD* adwHelpIDs)
  44. {
  45. m_pParentDlg = pOptionsPage;
  46. m_pGlobalInfo = pGlbDlg;
  47. m_adwHelpIDs = adwHelpIDs;
  48. }
  49. CIpSecDialog::~CIpSecDialog()
  50. {
  51. }
  52. LRESULT CIpSecDialog::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled)
  53. {
  54. HRESULT hr = S_OK;
  55. m_fInInitDialog = TRUE;
  56. // Does domain policy exist ?
  57. BOOL fHasDomainIpsecPolicy = FALSE;
  58. tstring strDomainIpsecPolicyName;
  59. hr = HrGetDomainIpsecPolicy( &fHasDomainIpsecPolicy, &strDomainIpsecPolicyName);
  60. if (SUCCEEDED(hr) && fHasDomainIpsecPolicy)
  61. hr = HrShowDomainIpsecPolicy(strDomainIpsecPolicyName.c_str());
  62. else
  63. hr = HrShowLocalIpsecPolicy();
  64. m_fInInitDialog = FALSE;
  65. if (FAILED(hr))
  66. {
  67. //$ TODO: Display a message box saying that an interal error occured. (Yuck.)
  68. EndDialog(IDCANCEL);
  69. }
  70. return 0;
  71. }
  72. LRESULT CIpSecDialog::OnDestroyDialog(UINT uMsg, WPARAM wParam,
  73. LPARAM lParam, BOOL& fHandled)
  74. {
  75. // Release the policy structures
  76. int nCount = Tcp_ComboBox_GetCount(GetDlgItem(IDC_CMB_IPSEC_POLICY_LIST));
  77. for (int idx=0; idx < nCount; idx++)
  78. {
  79. DWORD_PTR dw = SendDlgItemMessage(IDC_CMB_IPSEC_POLICY_LIST,
  80. CB_GETITEMDATA, idx, (LPARAM)0);
  81. if (0 != dw)
  82. {
  83. IPSEC_POLICY_INFO * pIpsecInfo = (IPSEC_POLICY_INFO *)dw;
  84. delete pIpsecInfo;
  85. }
  86. }
  87. return 0;
  88. }
  89. LRESULT CIpSecDialog::OnContextMenu(UINT uMsg, WPARAM wParam,
  90. LPARAM lParam, BOOL& fHandled)
  91. {
  92. ShowContextHelp(m_hWnd, HELP_CONTEXTMENU, m_adwHelpIDs);
  93. return 0;
  94. }
  95. LRESULT CIpSecDialog::OnHelp(UINT uMsg, WPARAM wParam,
  96. LPARAM lParam, BOOL& fHandled)
  97. {
  98. LPHELPINFO lphi = reinterpret_cast<LPHELPINFO>(lParam);
  99. Assert(lphi);
  100. if (HELPINFO_WINDOW == lphi->iContextType)
  101. {
  102. ShowContextHelp(static_cast<HWND>(lphi->hItemHandle), HELP_WM_HELP,
  103. m_adwHelpIDs);
  104. }
  105. return 0;
  106. }
  107. LRESULT CIpSecDialog::OnOk(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled)
  108. {
  109. // save the current selection
  110. if (IsDlgButtonChecked(IDC_RAD_IPSEC_NOIPSEC))
  111. {
  112. m_pGlobalInfo->m_strIpsecPol = c_szIpsecNoPol;
  113. }
  114. else if (IsDlgButtonChecked(IDC_RAD_IPSEC_CUSTOM))
  115. {
  116. int idx = SendDlgItemMessage(IDC_CMB_IPSEC_POLICY_LIST, CB_GETCURSEL, 0, 0);
  117. if (CB_ERR != idx)
  118. {
  119. DWORD_PTR dw = SendDlgItemMessage(IDC_CMB_IPSEC_POLICY_LIST,
  120. CB_GETITEMDATA, idx, (LPARAM)0);
  121. if (0 != dw)
  122. {
  123. IPSEC_POLICY_INFO * pIpsecInfo = (IPSEC_POLICY_INFO *)dw;
  124. m_pGlobalInfo->m_strIpsecPol = pIpsecInfo->szPolicyName;
  125. m_pGlobalInfo->m_guidIpsecPol = pIpsecInfo->guidPolicyId;
  126. }
  127. }
  128. }
  129. EndDialog(IDOK);
  130. return 0;
  131. }
  132. LRESULT CIpSecDialog::OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled)
  133. {
  134. EndDialog(IDCANCEL);
  135. return 0;
  136. }
  137. LRESULT CIpSecDialog::OnNoIpsec(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled)
  138. {
  139. switch(wNotifyCode)
  140. {
  141. case BN_CLICKED:
  142. case BN_DOUBLECLICKED:
  143. ::EnableWindow(GetDlgItem(IDC_CMB_IPSEC_POLICY_LIST), FALSE);
  144. ::EnableWindow(GetDlgItem(IDC_EDT_POLICY_DESC), FALSE);
  145. if (!m_fInInitDialog)
  146. m_pParentDlg->m_fPropDlgModified = TRUE;
  147. break;
  148. }
  149. return 0;
  150. }
  151. LRESULT CIpSecDialog::OnUseCustomPolicy(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled)
  152. {
  153. switch(wNotifyCode)
  154. {
  155. case BN_CLICKED:
  156. case BN_DOUBLECLICKED:
  157. ::EnableWindow(GetDlgItem(IDC_CMB_IPSEC_POLICY_LIST), TRUE);
  158. ::EnableWindow(GetDlgItem(IDC_EDT_POLICY_DESC), TRUE);
  159. if (!m_fInInitDialog)
  160. m_pParentDlg->m_fPropDlgModified = TRUE;
  161. break;
  162. }
  163. return 0;
  164. }
  165. LRESULT CIpSecDialog::OnSelectCustomPolicy(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& fHandled)
  166. {
  167. switch(wNotifyCode)
  168. {
  169. case CBN_SELCHANGE:
  170. // set description text
  171. int idx = SendDlgItemMessage(IDC_CMB_IPSEC_POLICY_LIST, CB_GETCURSEL, 0, 0);
  172. if (CB_ERR != idx)
  173. {
  174. DWORD_PTR dw = SendDlgItemMessage(IDC_CMB_IPSEC_POLICY_LIST,
  175. CB_GETITEMDATA, idx, (LPARAM)0);
  176. if (0 != dw)
  177. {
  178. IPSEC_POLICY_INFO * pIpsecInfo = (IPSEC_POLICY_INFO *)dw;
  179. SetDlgItemText(IDC_EDT_POLICY_DESC,pIpsecInfo->szPolicyDescription);
  180. }
  181. }
  182. if (!m_fInInitDialog)
  183. m_pParentDlg->m_fPropDlgModified = TRUE;
  184. break;
  185. }
  186. return 0;
  187. }
  188. // help functions
  189. HRESULT CIpSecDialog::HrGetDomainIpsecPolicy(BOOL * pfHasDomainIpsecPolicy,
  190. tstring * pstrDomainIpsecPolicyName)
  191. {
  192. HRESULT hr = S_OK;
  193. WCHAR szPolicyName[MAX_PATH];
  194. DWORD dwBufferSize = sizeof(szPolicyName);
  195. typedef HRESULT (WINAPI* PFNHrIsDomainPolicyAssigned)();
  196. typedef HRESULT (WINAPI* PFNHrGetAssignedDomainPolicyName)(PWSTR strPolicyName, DWORD *pdwBufferSize);
  197. // load the polstore dll and get the two export functions we need
  198. static const CHAR c_szHrIsDomainPolicyAssigned [] = "HrIsDomainPolicyAssigned";
  199. static const CHAR c_szHrGetAssignedDomainPolicyName [] = "HrGetAssignedDomainPolicyName";
  200. const PCSTR c_apszFunctionNames [2] =
  201. {
  202. c_szHrIsDomainPolicyAssigned,
  203. c_szHrGetAssignedDomainPolicyName
  204. };
  205. FARPROC apfn [2];
  206. HMODULE hPolStore;
  207. hr = HrLoadLibAndGetProcs ( L"polstore.dll", 2, c_apszFunctionNames,
  208. &hPolStore, apfn);
  209. if (S_OK == hr) // if both functions load successfully
  210. {
  211. PFNHrIsDomainPolicyAssigned pfnHrIsDomainPolicyAssigned =
  212. reinterpret_cast<PFNHrIsDomainPolicyAssigned>(apfn[0]);
  213. PFNHrGetAssignedDomainPolicyName pfnHrGetAssignedDomainPolicyName =
  214. reinterpret_cast<PFNHrGetAssignedDomainPolicyName>(apfn[1]);
  215. Assert(pfnHrIsDomainPolicyAssigned);
  216. Assert(pfnHrGetAssignedDomainPolicyName);
  217. szPolicyName[0] = L'\0';
  218. *pfHasDomainIpsecPolicy = FALSE;
  219. // One more IPSEC change: LSA is out, instead, read this key from
  220. // local registry. Should get updated every 8 hours.
  221. hr = (*pfnHrIsDomainPolicyAssigned)();
  222. if (hr == S_OK) {
  223. hr = (*pfnHrGetAssignedDomainPolicyName)(
  224. szPolicyName,
  225. &dwBufferSize
  226. );
  227. *pfHasDomainIpsecPolicy = TRUE;
  228. *pstrDomainIpsecPolicyName = SzLoadIds(IDS_DS_POLICY_PREFIX);
  229. *pstrDomainIpsecPolicyName += szPolicyName;
  230. }else {
  231. *pfHasDomainIpsecPolicy = FALSE;
  232. hr = S_OK;
  233. }
  234. // release the library
  235. FreeLibrary (hPolStore);
  236. }else {
  237. *pfHasDomainIpsecPolicy = FALSE;
  238. hr = S_OK;
  239. }
  240. TraceError("CIpSecDialog::HrGetDomainPolicy", hr);
  241. return hr;
  242. }
  243. HRESULT CIpSecDialog::HrShowDomainIpsecPolicy(PCWSTR pszDomainIpsecPolicyName)
  244. {
  245. Assert(pszDomainIpsecPolicyName);
  246. HRESULT hr = S_OK;
  247. // check the "custom" policy button and set const text to the combo box
  248. CheckDlgButton(IDC_RAD_IPSEC_CUSTOM, TRUE);
  249. SendDlgItemMessage(IDC_CMB_IPSEC_POLICY_LIST,
  250. CB_ADDSTRING, 0, (LPARAM)(pszDomainIpsecPolicyName));
  251. HWND hPolicyCombo = GetDlgItem(IDC_CMB_IPSEC_POLICY_LIST);
  252. Tcp_ComboBox_SetCurSel(hPolicyCombo, 0);
  253. // disable all controls on this doalog
  254. static const int nrgIdc[] = {IDC_RAD_IPSEC_NOIPSEC,
  255. IDC_RAD_IPSEC_CUSTOM,
  256. IDC_CMB_IPSEC_POLICY_LIST,
  257. IDC_STATIC,
  258. IDC_EDT_POLICY_DESC};
  259. EnableOrDisableDialogControls(m_hWnd, celems(nrgIdc), nrgIdc, FALSE);
  260. TraceError("CIpSecDialog::HrShowDomainIpsecPolicy", hr);
  261. return hr;
  262. }
  263. HRESULT CIpSecDialog::HrShowLocalIpsecPolicy()
  264. {
  265. HRESULT hr = S_OK;
  266. typedef HRESULT (WINAPI* PFNHrGetLocalIpSecPolicyList)(C_IPSEC_POLICY_INFO ** ppPolicyInfoList,
  267. C_IPSEC_POLICY_INFO ** ppActivePolicyInfo);
  268. typedef HRESULT (WINAPI* PFNHrFreeLocalIpSecPolicyList)(C_IPSEC_POLICY_INFO * pPolicyInfoList);
  269. // load the polstore dll and get the two export functions we need
  270. static const CHAR c_szHrGetLocalIpSecPolicyList [] = "HrGetLocalIpSecPolicyList";
  271. static const CHAR c_szHrFreeLocalIpSecPolicyList [] = "HrFreeLocalIpSecPolicyList";
  272. const PCSTR c_apszFunctionNames [2] =
  273. {
  274. c_szHrGetLocalIpSecPolicyList,
  275. c_szHrFreeLocalIpSecPolicyList
  276. };
  277. FARPROC apfn [2];
  278. HMODULE hPolStore;
  279. hr = HrLoadLibAndGetProcs ( L"polstore.dll", 2, c_apszFunctionNames,
  280. &hPolStore, apfn);
  281. if (S_OK == hr) // if both functions load successfully
  282. {
  283. PFNHrGetLocalIpSecPolicyList pfnHrGetLocalIpSecPolicyList =
  284. reinterpret_cast<PFNHrGetLocalIpSecPolicyList>(apfn[0]);
  285. PFNHrFreeLocalIpSecPolicyList pfnHrFreeLocalIpSecPolicyList =
  286. reinterpret_cast<PFNHrFreeLocalIpSecPolicyList>(apfn[1]);
  287. Assert(pfnHrGetLocalIpSecPolicyList);
  288. Assert(pfnHrFreeLocalIpSecPolicyList);
  289. // variables for the policies
  290. C_IPSEC_POLICY_INFO* pPolicyInfoList = NULL;
  291. C_IPSEC_POLICY_INFO* pActivePolicyInfo = NULL;
  292. // get the list of policies
  293. HRESULT hr = (*pfnHrGetLocalIpSecPolicyList)(&pPolicyInfoList,
  294. &pActivePolicyInfo);
  295. if (SUCCEEDED(hr))
  296. {
  297. // loop through all the policies, insert custom policies to the combo-box
  298. C_IPSEC_POLICY_INFO * pCurPolicyInfoList = pPolicyInfoList;
  299. while (pCurPolicyInfoList)
  300. {
  301. IPSEC_POLICY_INFO * pPolInfo = new IPSEC_POLICY_INFO;
  302. if (NULL == pPolInfo)
  303. {
  304. hr = E_OUTOFMEMORY;
  305. continue;
  306. }
  307. pPolInfo->guidPolicyId = pCurPolicyInfoList->guidPolicyId;
  308. lstrcpyW(pPolInfo->szPolicyName, pCurPolicyInfoList->szPolicyName);
  309. lstrcpyW(pPolInfo->szPolicyDescription, pCurPolicyInfoList->szPolicyDescription);
  310. int idx;
  311. idx = SendDlgItemMessage(IDC_CMB_IPSEC_POLICY_LIST, CB_ADDSTRING, 0,
  312. (LPARAM)(pCurPolicyInfoList->szPolicyName));
  313. if (idx != CB_ERR)
  314. SendDlgItemMessage(IDC_CMB_IPSEC_POLICY_LIST,
  315. CB_SETITEMDATA, idx, (LPARAM)pPolInfo);
  316. pCurPolicyInfoList = pCurPolicyInfoList->pNextPolicyInfo;
  317. }
  318. // now set active policy
  319. if (m_pGlobalInfo->m_strIpsecPol != c_szIpsecUnset)
  320. {
  321. if (m_pGlobalInfo->m_strIpsecPol == c_szIpsecNoPol)
  322. {
  323. // no ipsec
  324. hr = HrSelectActivePolicy(NULL);
  325. Assert(S_OK == hr); // this should always succeed
  326. }
  327. else
  328. {
  329. hr = HrSelectActivePolicy(&(m_pGlobalInfo->m_guidIpsecPol));
  330. if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  331. {
  332. // policy does not exist
  333. // NYI:pop-up message that the previous (custom) policy is no longer available
  334. if (pActivePolicyInfo)
  335. hr = HrSelectActivePolicy(&(pActivePolicyInfo->guidPolicyId));
  336. else
  337. hr = HrSelectActivePolicy(NULL);
  338. Assert(S_OK == hr); // this should always succeed
  339. }
  340. }
  341. }
  342. else
  343. {
  344. if (pActivePolicyInfo)
  345. hr = HrSelectActivePolicy(&(pActivePolicyInfo->guidPolicyId));
  346. else
  347. hr = HrSelectActivePolicy(NULL);
  348. Assert(S_OK == hr); // this should always succeed
  349. }
  350. // disabled the combo-box and radio button if no custom policy
  351. if (0 == Tcp_ComboBox_GetCount(GetDlgItem(IDC_CMB_IPSEC_POLICY_LIST)))
  352. {
  353. ::EnableWindow(GetDlgItem(IDC_CMB_IPSEC_POLICY_LIST), FALSE);
  354. ::EnableWindow(GetDlgItem(IDC_EDT_POLICY_DESC), FALSE);
  355. ::EnableWindow(GetDlgItem(IDC_RAD_IPSEC_CUSTOM), FALSE);
  356. }
  357. if (pPolicyInfoList)
  358. {
  359. HRESULT hrT = (*pfnHrFreeLocalIpSecPolicyList)(pPolicyInfoList);
  360. if (FAILED(hrT))
  361. {
  362. TraceTag(ttidError, "HrFreeLocalIpSecPolicyList returned failure, hr = %x", hrT);
  363. }
  364. }
  365. }
  366. // release the library
  367. FreeLibrary (hPolStore);
  368. }
  369. else
  370. {
  371. // if failed to get the two export functions from polstore.dll
  372. TraceTag(ttidError, "Failed to load polstore.dll or get export function handle.");
  373. hr = E_FAIL;
  374. }
  375. TraceError("CIpSecDialog::HrShowLocalIpsecPolicy", hr);
  376. return hr;
  377. }
  378. HRESULT CIpSecDialog::HrSelectActivePolicy(GUID * pguidPolicyId)
  379. {
  380. HRESULT hr = S_OK;
  381. HWND hPolicyCombo = GetDlgItem(IDC_CMB_IPSEC_POLICY_LIST);
  382. if (!pguidPolicyId)
  383. {
  384. CheckDlgButton(IDC_RAD_IPSEC_NOIPSEC, TRUE);
  385. Tcp_ComboBox_SetCurSel(hPolicyCombo, 0);
  386. }
  387. else
  388. {
  389. BOOL fFound = FALSE;
  390. // check if any available custom policy match this policy
  391. IPSEC_POLICY_INFO * pPolInfo;
  392. int nCount = Tcp_ComboBox_GetCount(hPolicyCombo);
  393. for (int i=0; i<nCount; i++)
  394. {
  395. pPolInfo = NULL;
  396. DWORD_PTR dw = ::SendMessage(hPolicyCombo, CB_GETITEMDATA, i, (LPARAM)0);
  397. if ((CB_ERR != dw) && (0 != dw))
  398. pPolInfo = (IPSEC_POLICY_INFO *)dw;
  399. if (pPolInfo->guidPolicyId == *pguidPolicyId)
  400. {
  401. fFound = TRUE;
  402. CheckDlgButton(IDC_RAD_IPSEC_CUSTOM, TRUE);
  403. Tcp_ComboBox_SetCurSel(hPolicyCombo, i);
  404. break;
  405. }
  406. }
  407. if (!fFound)
  408. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  409. }
  410. if (SUCCEEDED(hr))
  411. {
  412. // set description text
  413. int idx = SendDlgItemMessage(IDC_CMB_IPSEC_POLICY_LIST, CB_GETCURSEL, 0, 0);
  414. if (CB_ERR != idx)
  415. {
  416. DWORD_PTR dw = SendDlgItemMessage(IDC_CMB_IPSEC_POLICY_LIST,
  417. CB_GETITEMDATA, idx, (LPARAM)0);
  418. if (0 != dw)
  419. {
  420. IPSEC_POLICY_INFO * pIpsecInfo = (IPSEC_POLICY_INFO *)dw;
  421. SetDlgItemText(IDC_EDT_POLICY_DESC,pIpsecInfo->szPolicyDescription);
  422. }
  423. }
  424. }
  425. if (!pguidPolicyId)
  426. {
  427. ::EnableWindow(hPolicyCombo, FALSE);
  428. ::EnableWindow(GetDlgItem(IDC_EDT_POLICY_DESC), FALSE);
  429. }
  430. TraceError("CIpSecDialog::HrSelectActivePolicy", hr);
  431. return hr;
  432. }