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.

735 lines
21 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation **/
  4. /**********************************************************************/
  5. /*
  6. dlgdial.cpp
  7. This files contains the implementation of class CDlgRasDialin
  8. which is the class to represent the property page appears on
  9. user object property sheet as tab "RAS dial-in"
  10. FILE HISTORY:
  11. */
  12. #include "stdafx.h"
  13. #include <sspi.h>
  14. #include <secext.h>
  15. #include <raserror.h>
  16. #include <adsprop.h>
  17. #include "helper.h"
  18. #include "resource.h"
  19. #include "DlgDial.h"
  20. #include "DlgRoute.h"
  21. #include "profsht.h"
  22. #include "helptable.h"
  23. #include "rasprof.h"
  24. #include "commctrl.h"
  25. #ifdef _DEBUG
  26. #define new DEBUG_NEW
  27. #undef THIS_FILE
  28. static char THIS_FILE[] = __FILE__;
  29. #endif
  30. const wchar_t* ALLOW_DIALIN_NAME = L"msNPAllowDialin";
  31. const wchar_t* NP_CALLING_STATION_ID_NAME = L"msNPCallingStationID";
  32. const wchar_t* CALLBACK_NUMBER_NAME = L"msRADIUSCallbackNumber";
  33. const wchar_t* FRAMED_IP_ADDRESS_NAME = L"msRADIUSFramedIPAddress";
  34. const wchar_t* FRAMED_ROUTE_NAME = L"msRADIUSFramedRoute";
  35. const wchar_t* SERVICE_TYPE_NAME = L"msRADIUSServiceType";
  36. /////////////////////////////////////////////////////////////////////////////
  37. // CDlgRASDialinMerge dialog
  38. IMPLEMENT_DYNAMIC(CDlgRASDialinMerge, CPropertyPage)
  39. CDlgRASDialinMerge::~CDlgRASDialinMerge()
  40. {
  41. Reset();
  42. }
  43. CDlgRASDialinMerge::CDlgRASDialinMerge()
  44. : CPropertyPage(CDlgRASDialinMerge::IDD),
  45. CRASUserMerge(RASUSER_ENV_LOCAL, NULL, NULL)
  46. {
  47. // initialize the memebers
  48. Reset();
  49. }
  50. CDlgRASDialinMerge::CDlgRASDialinMerge(
  51. RasEnvType type,
  52. LPCWSTR location,
  53. LPCWSTR userPath,
  54. HWND notifyObj
  55. )
  56. : CPropertyPage(CDlgRASDialinMerge::IDD),
  57. CRASUserMerge(type, location, userPath)
  58. {
  59. if (type == RASUSER_ENV_DS)
  60. {
  61. ADSPROPINITPARAMS initParams;
  62. initParams.dwSize = sizeof (ADSPROPINITPARAMS);
  63. if (!ADsPropGetInitInfo(notifyObj, &initParams))
  64. {
  65. AfxThrowOleException(E_FAIL);
  66. }
  67. if (FAILED(initParams.hr))
  68. {
  69. AfxThrowOleException(initParams.hr);
  70. }
  71. m_pWritableAttrs = initParams.pWritableAttrs;
  72. }
  73. else
  74. {
  75. m_pWritableAttrs = NULL;
  76. }
  77. // initialize the memebers
  78. Reset();
  79. }
  80. void CDlgRASDialinMerge::Reset()
  81. {
  82. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  83. //{{AFX_DATA_INIT(CDlgRASDialinMerge)
  84. m_bApplyStaticRoutes = FALSE;
  85. m_nCurrentProfileIndex = 0;
  86. m_bCallingStationId = FALSE;
  87. m_bOverride = FALSE;
  88. m_nDialinPermit = -1;
  89. //}}AFX_DATA_INIT
  90. // Need to save the original callback pointer because we are replacing
  91. // it with our own
  92. m_pfnOriginalCallback = m_psp.pfnCallback;
  93. m_pEditIPAddress = NULL;
  94. // init for using IPAddress common control
  95. INITCOMMONCONTROLSEX INITEX;
  96. INITEX.dwSize = sizeof(INITCOMMONCONTROLSEX);
  97. INITEX.dwICC = ICC_INTERNET_CLASSES;
  98. ::InitCommonControlsEx(&INITEX);
  99. m_bInitFailed = FALSE;
  100. m_bModified = FALSE;
  101. }
  102. void CDlgRASDialinMerge::DoDataExchange(CDataExchange* pDX)
  103. {
  104. if(m_bInitFailed)
  105. return;
  106. /*
  107. USHORT
  108. WINAPI
  109. CompressPhoneNumber(
  110. IN LPWSTR Uncompressed,
  111. OUT LPWSTR Compressed
  112. );
  113. */
  114. CPropertyPage::DoDataExchange(pDX);
  115. //{{AFX_DATA_MAP(CDlgRASDialinMerge)
  116. DDX_Control(pDX, IDC_CHECKSTATICIPADDRESS, m_CheckStaticIPAddress);
  117. DDX_Control(pDX, IDC_CHECKCALLERID, m_CheckCallerId);
  118. DDX_Control(pDX, IDC_CHECKAPPLYSTATICROUTES, m_CheckApplyStaticRoutes);
  119. DDX_Control(pDX, IDC_RADIONOCALLBACK, m_RadioNoCallback);
  120. DDX_Control(pDX, IDC_RADIOSETBYCALLER, m_RadioSetByCaller);
  121. DDX_Control(pDX, IDC_RADIOSECURECALLBACKTO, m_RadioSecureCallbackTo);
  122. DDX_Control(pDX, IDC_EDITCALLERID, m_EditCallerId);
  123. DDX_Control(pDX, IDC_EDITCALLBACK, m_EditCallback);
  124. DDX_Control(pDX, IDC_BUTTONSTATICROUTES, m_ButtonStaticRoutes);
  125. DDX_Check(pDX, IDC_CHECKAPPLYSTATICROUTES, m_bApplyStaticRoutes);
  126. DDX_Radio(pDX, IDC_RADIONOCALLBACK, m_nCallbackPolicy);
  127. DDX_Check(pDX, IDC_CHECKCALLERID, m_bCallingStationId);
  128. DDX_Check(pDX, IDC_CHECKSTATICIPADDRESS, m_bOverride);
  129. DDX_Radio(pDX, IDC_PERMIT_ALLOW, m_nDialinPermit);
  130. //}}AFX_DATA_MAP
  131. DDX_Text(pDX, IDC_EDITCALLERID, m_strCallingStationId);
  132. DDX_Text(pDX, IDC_EDITCALLBACK, m_strCallbackNumber);
  133. if(S_OK == HrIsInMixedDomain() || m_type == RASUSER_ENV_LOCAL) // user in mixed domain
  134. {
  135. DWORD dwErr = 0;
  136. typedef USHORT (WINAPI *COMPRESSCALLBACKFUNC)(
  137. IN LPWSTR Uncompressed,
  138. OUT LPWSTR Compressed);
  139. WCHAR tempBuf[RAS_CALLBACK_NUMBER_LEN_NT4 + 2];
  140. DDV_MaxChars(pDX, m_strCallbackNumber, RAS_CALLBACK_NUMBER_LEN_NT4);
  141. COMPRESSCALLBACKFUNC pfnCompressCallback = NULL;
  142. HMODULE hMprApiDLL = NULL;
  143. hMprApiDLL = LoadLibrary(_T("mprapi.dll"));
  144. if ( NULL != hMprApiDLL )
  145. {
  146. // load the API pointer
  147. pfnCompressCallback = (COMPRESSCALLBACKFUNC) GetProcAddress(hMprApiDLL, "CompressPhoneNumber");
  148. if(NULL != pfnCompressCallback)
  149. {
  150. dwErr = pfnCompressCallback((LPTSTR)(LPCTSTR)m_strCallbackNumber, tempBuf);
  151. switch(dwErr)
  152. {
  153. case ERROR_BAD_LENGTH:
  154. AfxMessageBox(IDS_ERR_CALLBACK_TOO_LONG);
  155. pDX->Fail();
  156. break;
  157. case ERROR_BAD_CALLBACK_NUMBER:
  158. AfxMessageBox(IDS_ERR_CALLBACK_INVALID);
  159. pDX->Fail();
  160. break;
  161. }
  162. }
  163. }
  164. }
  165. else
  166. {
  167. DDV_MaxChars(pDX, m_strCallbackNumber, RAS_CALLBACK_NUMBER_LEN);
  168. }
  169. if(pDX->m_bSaveAndValidate) // save data to this class
  170. {
  171. // ip adress control
  172. if(m_pEditIPAddress->SendMessage(IPM_GETADDRESS, 0, (LPARAM)&m_dwFramedIPAddress))
  173. m_bStaticIPAddress = TRUE;
  174. else
  175. m_bStaticIPAddress = FALSE;
  176. }
  177. else // put to dialog
  178. {
  179. // ip adress control
  180. if(m_bStaticIPAddress)
  181. m_pEditIPAddress->SendMessage(IPM_SETADDRESS, 0, m_dwFramedIPAddress);
  182. else
  183. m_pEditIPAddress->SendMessage(IPM_CLEARADDRESS, 0, m_dwFramedIPAddress);
  184. }
  185. }
  186. BEGIN_MESSAGE_MAP(CDlgRASDialinMerge, CPropertyPage)
  187. //{{AFX_MSG_MAP(CDlgRASDialinMerge)
  188. ON_BN_CLICKED(IDC_BUTTONSTATICROUTES, OnButtonStaticRoutes)
  189. ON_BN_CLICKED(IDC_CHECKAPPLYSTATICROUTES, OnCheckApplyStaticRoutes)
  190. ON_BN_CLICKED(IDC_CHECKCALLERID, OnCheckCallerId)
  191. ON_BN_CLICKED(IDC_RADIOSECURECALLBACKTO, OnRadioSecureCallbackTo)
  192. ON_BN_CLICKED(IDC_RADIONOCALLBACK, OnRadioNoCallback)
  193. ON_BN_CLICKED(IDC_RADIOSETBYCALLER, OnRadioSetByCaller)
  194. ON_BN_CLICKED(IDC_CHECKSTATICIPADDRESS, OnCheckStaticIPAddress)
  195. ON_WM_HELPINFO()
  196. ON_WM_CONTEXTMENU()
  197. ON_EN_CHANGE(IDC_EDITCALLBACK, OnChangeEditcallback)
  198. ON_EN_CHANGE(IDC_EDITCALLERID, OnChangeEditcallerid)
  199. ON_WM_CREATE()
  200. ON_BN_CLICKED(IDC_PERMIT_ALLOW, OnPermitAllow)
  201. ON_BN_CLICKED(IDC_PERMIT_DENY, OnPermitDeny)
  202. ON_BN_CLICKED(IDC_PERMIT_POLICY, OnPermitPolicy)
  203. ON_WM_DESTROY()
  204. ON_NOTIFY(IPN_FIELDCHANGED, IDC_EDITIPADDRESS, OnFieldchangedEditipaddress)
  205. //}}AFX_MSG_MAP
  206. END_MESSAGE_MAP()
  207. /////////////////////////////////////////////////////////////////////////////
  208. // CDlgRASDialinMerge message handlers
  209. // called when static routes button is pressed
  210. void CDlgRASDialinMerge::OnButtonStaticRoutes()
  211. {
  212. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  213. CDlgStaticRoutes DlgRoutes(m_strArrayFramedRoute, this);
  214. try{
  215. if(DlgRoutes.DoModal() == IDOK)
  216. {
  217. SetModified();
  218. };
  219. }
  220. catch(CMemoryException* pException)
  221. {
  222. pException->Delete();
  223. }
  224. // uncheck the checkbox if it's empty
  225. if(m_strArrayFramedRoute.GetSize() == 0)
  226. {
  227. m_CheckApplyStaticRoutes.SetCheck(FALSE);
  228. OnCheckApplyStaticRoutes();
  229. }
  230. }
  231. // when checkbox -- apply static routes is clicked
  232. void CDlgRASDialinMerge::OnCheckApplyStaticRoutes()
  233. {
  234. SetModified();
  235. // if checkbox "Apply static routes" is checked
  236. m_bApplyStaticRoutes = m_CheckApplyStaticRoutes.GetCheck();
  237. // Enable / Disable the push button for editing static routes
  238. m_ButtonStaticRoutes.EnableWindow(m_bApplyStaticRoutes);
  239. if(m_bApplyStaticRoutes && m_strArrayFramedRoute.GetSize() == 0)
  240. OnButtonStaticRoutes();
  241. }
  242. // when checkbox -- callerId is clicked
  243. void CDlgRASDialinMerge::OnCheckCallerId()
  244. {
  245. SetModified();
  246. // Disable or enable the edit box for caller id
  247. m_EditCallerId.EnableWindow(m_CheckCallerId.GetCheck());
  248. }
  249. // enable / disable the each items accroding to current state
  250. void CDlgRASDialinMerge::EnableDialinSettings()
  251. {
  252. BOOL bEnable;
  253. bEnable = IsPropertyWritable(ALLOW_DIALIN_NAME);
  254. EnableAccessControl(bEnable);
  255. // related to caller Id
  256. bEnable = IsPropertyWritable(NP_CALLING_STATION_ID_NAME);
  257. EnableCallerId(bEnable);
  258. // related to callback
  259. bEnable = IsPropertyWritable(CALLBACK_NUMBER_NAME) &&
  260. IsPropertyWritable(SERVICE_TYPE_NAME);
  261. EnableCallback(bEnable);
  262. // related to Ip address
  263. bEnable = IsPropertyWritable(FRAMED_IP_ADDRESS_NAME);
  264. EnableIPAddress(bEnable);
  265. // related to static routes
  266. bEnable = IsPropertyWritable(FRAMED_ROUTE_NAME);
  267. EnableStaticRoutes(bEnable);
  268. // if user in mixed domain, only allow to set dialin bit and callback options
  269. if(S_OK == HrIsInMixedDomain()) // user in mixed domain
  270. {
  271. GetDlgItem(IDC_PERMIT_POLICY)->EnableWindow(FALSE);
  272. // calling station id
  273. GetDlgItem(IDC_CHECKCALLERID)->EnableWindow(FALSE);
  274. GetDlgItem(IDC_EDITCALLERID)->EnableWindow(FALSE);
  275. // framed IP address
  276. GetDlgItem(IDC_CHECKSTATICIPADDRESS)->EnableWindow(FALSE);
  277. GetDlgItem(IDC_EDITIPADDRESS)->EnableWindow(FALSE);
  278. // framed route
  279. GetDlgItem(IDC_CHECKAPPLYSTATICROUTES)->EnableWindow(FALSE);
  280. GetDlgItem(IDC_BUTTONSTATICROUTES)->EnableWindow(FALSE);
  281. }
  282. }
  283. // called when clicked on NoCallback radio button
  284. void CDlgRASDialinMerge::OnRadioNoCallback()
  285. {
  286. SetModified();
  287. // disable the edit box for callback
  288. m_EditCallback.EnableWindow(false);
  289. }
  290. void CDlgRASDialinMerge::OnRadioSetByCaller()
  291. {
  292. SetModified();
  293. // disable the edit box for callback
  294. m_EditCallback.EnableWindow(false);
  295. }
  296. void CDlgRASDialinMerge::OnRadioSecureCallbackTo()
  297. {
  298. SetModified();
  299. // enable the edit box for callback
  300. m_EditCallback.EnableWindow(true);
  301. }
  302. BOOL CDlgRASDialinMerge::IsPropertyWritable(
  303. const wchar_t* propName
  304. ) const throw ()
  305. {
  306. return IsFocusOnLocalUser() ||
  307. ADsPropCheckIfWritable(
  308. const_cast<wchar_t*>(propName),
  309. m_pWritableAttrs
  310. );
  311. }
  312. void CDlgRASDialinMerge::EnableAccessControl(BOOL bEnable)
  313. {
  314. GetDlgItem(IDC_PERMIT_ALLOW)->EnableWindow(bEnable);
  315. GetDlgItem(IDC_PERMIT_DENY)->EnableWindow(bEnable);
  316. GetDlgItem(IDC_PERMIT_POLICY)->EnableWindow(bEnable);
  317. }
  318. void CDlgRASDialinMerge::EnableCallerId(BOOL bEnable)
  319. {
  320. // checkbox -- caller id
  321. m_CheckCallerId.EnableWindow(bEnable);
  322. // edit box -- caller id
  323. m_EditCallerId.EnableWindow(bEnable && m_CheckCallerId.GetCheck());
  324. }
  325. void CDlgRASDialinMerge::EnableCallback(BOOL bEnable)
  326. {
  327. // radio button -- no call back
  328. m_RadioNoCallback.EnableWindow(bEnable);
  329. // radio button -- set by caller
  330. m_RadioSetByCaller.EnableWindow(bEnable);
  331. // radio button -- secure callback to
  332. m_RadioSecureCallbackTo.EnableWindow(bEnable);
  333. // edit box -- callback
  334. m_EditCallback.EnableWindow(m_RadioSecureCallbackTo.GetCheck());
  335. }
  336. void CDlgRASDialinMerge::EnableIPAddress(BOOL bEnable)
  337. {
  338. m_CheckStaticIPAddress.SetCheck(m_bOverride);
  339. m_CheckStaticIPAddress.EnableWindow(bEnable);
  340. m_pEditIPAddress->EnableWindow(bEnable && m_bOverride);
  341. }
  342. void CDlgRASDialinMerge::EnableStaticRoutes(BOOL bEnable)
  343. {
  344. // check box -- apply static routes
  345. m_CheckApplyStaticRoutes.EnableWindow(bEnable);
  346. if(!m_bApplyStaticRoutes) bEnable = false;
  347. // push button -- static routes
  348. m_ButtonStaticRoutes.EnableWindow(bEnable);
  349. }
  350. int CDlgRASDialinMerge::OnCreate(LPCREATESTRUCT lpCreateStruct)
  351. {
  352. return CPropertyPage::OnCreate(lpCreateStruct);
  353. }
  354. // called when dialog is created
  355. BOOL CDlgRASDialinMerge::OnInitDialog()
  356. {
  357. HRESULT hr = Load();
  358. if FAILED(hr)
  359. {
  360. ReportError(hr, IDS_ERR_LOADUSER, m_hWnd);
  361. }
  362. else if (hr == S_FALSE) // Not the right OS to run
  363. {
  364. AfxMessageBox(IDS_ERR_NOTNT5SRV);
  365. }
  366. if(hr != S_OK)
  367. {
  368. EnableChildControls(GetSafeHwnd(), PROPPAGE_CHILD_HIDE | PROPPAGE_CHILD_DISABLE);
  369. GetDlgItem(IDC_FAILED_TO_INIT)->ShowWindow(SW_SHOW);
  370. GetDlgItem(IDC_FAILED_TO_INIT)->EnableWindow(TRUE);
  371. m_bInitFailed = TRUE;
  372. return TRUE;
  373. }
  374. if(m_strArrayCallingStationId.GetSize())
  375. m_strCallingStationId = *m_strArrayCallingStationId[(INT_PTR)0];
  376. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  377. m_pEditIPAddress = GetDlgItem(IDC_EDITIPADDRESS);
  378. CPropertyPage::OnInitDialog();
  379. SetModified(FALSE);
  380. EnableDialinSettings();
  381. return TRUE; // return TRUE unless you set the focus to a control
  382. // EXCEPTION: OCX Property Pages should return FALSE
  383. }
  384. // called when click on OK or Apply button, if modify flag is set
  385. BOOL CDlgRASDialinMerge::OnApply()
  386. {
  387. HRESULT hr = S_OK;
  388. if(m_bInitFailed)
  389. goto L_Exit;
  390. if (!GetModified())
  391. return CPropertyPage::OnApply();
  392. m_dwDefinedAttribMask = 0;
  393. // dialin bit
  394. switch(m_nDialinPermit)
  395. {
  396. case 0: // allow
  397. m_dwDialinPermit = 1;
  398. break;
  399. case 1: // deny
  400. m_dwDialinPermit = 0;
  401. break;
  402. case 2: // policy decide -- remove the attribute from user object
  403. m_dwDialinPermit = -1;
  404. break;
  405. }
  406. // caller id
  407. if(m_bCallingStationId && !m_strCallingStationId.IsEmpty())
  408. m_dwDefinedAttribMask |= RAS_USE_CALLERID;
  409. m_strArrayCallingStationId.DeleteAll();
  410. if(!m_strCallingStationId.IsEmpty())
  411. {
  412. CString* pStr = new CString(m_strCallingStationId);
  413. if(pStr)
  414. m_strArrayCallingStationId.Add(pStr);
  415. }
  416. // callback option
  417. switch(m_nCallbackPolicy)
  418. {
  419. case 0: // no callback
  420. m_dwDefinedAttribMask |= RAS_CALLBACK_NOCALLBACK;
  421. break;
  422. case 1: // set by caller
  423. m_dwDefinedAttribMask |= RAS_CALLBACK_CALLERSET;
  424. break;
  425. case 2: // secure callback
  426. m_dwDefinedAttribMask |= RAS_CALLBACK_SECURE;
  427. break;
  428. }
  429. // Ip Address
  430. if(m_bOverride && m_dwFramedIPAddress)
  431. m_dwDefinedAttribMask |= RAS_USE_STATICIP;
  432. // Static Routes
  433. if(m_bApplyStaticRoutes && m_strArrayFramedRoute.GetSize())
  434. m_dwDefinedAttribMask |= RAS_USE_STATICROUTES;
  435. // save the user object
  436. hr = Save();
  437. L_Exit:
  438. if (FAILED(hr))
  439. {
  440. ReportError(hr, IDS_ERR_SAVEUSER, m_hWnd);
  441. }
  442. return CPropertyPage::OnApply();
  443. }
  444. void CDlgRASDialinMerge::OnCheckStaticIPAddress()
  445. {
  446. SetModified();
  447. m_bStaticIPAddress = m_CheckStaticIPAddress.GetCheck();
  448. m_pEditIPAddress->EnableWindow(m_bStaticIPAddress);
  449. }
  450. HRESULT CDlgRASDialinMerge::Load()
  451. {
  452. HRESULT hr = S_OK;
  453. // Load the data from DS
  454. CHECK_HR(hr = CRASUserMerge::Load());
  455. if(hr != S_OK)
  456. return hr;
  457. // dialin bit
  458. if(m_dwDialinPermit == 1) //allow dialin
  459. m_nDialinPermit = 0;
  460. else if(m_dwDialinPermit == -1) // Policy defines dialin bit -- not defined per user
  461. m_nDialinPermit = 2;
  462. else
  463. m_nDialinPermit = 1; //deny dialin
  464. // in the case of Local User Manager, the Policy defined by profile is disableed
  465. if(S_OK == HrIsInMixedDomain() && m_nDialinPermit == 2) // Local case
  466. {
  467. m_nDialinPermit = 1; // deny
  468. }
  469. // callback policy
  470. if(!(m_dwDefinedAttribMask & RAS_CALLBACK_MASK))
  471. m_nCallbackPolicy = 0;
  472. else if(m_dwDefinedAttribMask & RAS_CALLBACK_CALLERSET)
  473. m_nCallbackPolicy = 1;
  474. else if(m_dwDefinedAttribMask & RAS_CALLBACK_SECURE)
  475. m_nCallbackPolicy = 2;
  476. else if(m_dwDefinedAttribMask & RAS_CALLBACK_NOCALLBACK)
  477. m_nCallbackPolicy = 0;
  478. //=============================================================================
  479. // change to use dwAllowDialin to hold if static Route, calling station id
  480. // if ras user object required there is a staic ip
  481. if(m_dwDefinedAttribMask & RAS_USE_STATICIP)
  482. m_bOverride = TRUE;
  483. m_bStaticIPAddress = (m_dwFramedIPAddress != 0);
  484. // static routes
  485. m_bApplyStaticRoutes = (m_dwDefinedAttribMask & RAS_USE_STATICROUTES) && (m_strArrayFramedRoute.GetSize() != 0);
  486. // calling station
  487. m_bCallingStationId = (m_dwDefinedAttribMask & RAS_USE_CALLERID) && m_strArrayCallingStationId.GetSize() && (m_strArrayCallingStationId[(INT_PTR)0]->GetLength() != 0);
  488. L_ERR:
  489. return hr;
  490. }
  491. BOOL CDlgRASDialinMerge::OnHelpInfo(HELPINFO* pHelpInfo)
  492. {
  493. ::WinHelp ((HWND)pHelpInfo->hItemHandle,
  494. AfxGetApp()->m_pszHelpFilePath,
  495. HELP_WM_HELP,
  496. (DWORD_PTR)(LPVOID)g_aHelpIDs_IDD_RASDIALIN_MERGE);
  497. return CPropertyPage::OnHelpInfo(pHelpInfo);
  498. }
  499. void CDlgRASDialinMerge::OnContextMenu(CWnd* pWnd, CPoint point)
  500. {
  501. ::WinHelp (pWnd->m_hWnd, AfxGetApp()->m_pszHelpFilePath,
  502. HELP_CONTEXTMENU, (DWORD_PTR)(LPVOID)g_aHelpIDs_IDD_RASDIALIN_MERGE);
  503. }
  504. BOOL CDlgRASDialinMerge::OnKillActive()
  505. {
  506. UINT ids = 0;
  507. if(m_bInitFailed)
  508. return CPropertyPage::OnKillActive();
  509. if(FALSE == CPropertyPage::OnKillActive()) return FALSE;
  510. if(m_bCallingStationId && m_strCallingStationId.IsEmpty())
  511. {
  512. GotoDlgCtrl( &m_EditCallerId );
  513. ids = IDS_NEED_CALLER_ID;
  514. goto L_ERR;
  515. }
  516. // callback option
  517. // always callback to
  518. if(m_nCallbackPolicy == 2 && m_strCallbackNumber.IsEmpty())
  519. {
  520. GotoDlgCtrl( &m_EditCallback );
  521. ids = IDS_NEED_CALLBACK_NUMBER;
  522. goto L_ERR;
  523. }
  524. // Ip Address
  525. if(m_bOverride && !m_bStaticIPAddress )
  526. {
  527. GotoDlgCtrl( m_pEditIPAddress );
  528. ids = IDS_NEED_IPADDRESS;
  529. goto L_ERR;
  530. }
  531. // Static Routes
  532. if(m_bApplyStaticRoutes && m_strArrayFramedRoute.GetSize() == 0)
  533. {
  534. GotoDlgCtrl( &m_CheckApplyStaticRoutes );
  535. goto L_ERR;
  536. }
  537. return TRUE;
  538. L_ERR:
  539. if (ids != 0)
  540. AfxMessageBox(ids);
  541. return FALSE;
  542. }
  543. //---------------------------------------------------------------------------
  544. // This is our self deleting callback function. If you have more than a
  545. // a few property sheets, it might be a good idea to implement this in a
  546. // base class and derive your MFC property sheets from the base class
  547. //
  548. UINT CALLBACK CDlgRASDialinMerge::PropSheetPageProc
  549. (
  550. HWND hWnd, // [in] Window handle - always null
  551. UINT uMsg, // [in,out] Either the create or delete message
  552. LPPROPSHEETPAGE pPsp // [in,out] Pointer to the property sheet struct
  553. )
  554. {
  555. ASSERT( NULL != pPsp );
  556. // We need to recover a pointer to the current instance. We can't just use
  557. // "this" because we are in a static function
  558. CDlgRASDialinMerge* pMe = reinterpret_cast<CDlgRASDialinMerge*>(pPsp->lParam);
  559. ASSERT( NULL != pMe );
  560. switch( uMsg )
  561. {
  562. case PSPCB_CREATE:
  563. break;
  564. case PSPCB_RELEASE:
  565. // Since we are deleting ourselves, save a callback on the stack
  566. // so we can callback the base class
  567. LPFNPSPCALLBACK pfnOrig = pMe->m_pfnOriginalCallback;
  568. delete pMe;
  569. return 1; //(pfnOrig)(hWnd, uMsg, pPsp);
  570. }
  571. // Must call the base class callback function or none of the MFC
  572. // message map stuff will work
  573. return (pMe->m_pfnOriginalCallback)(hWnd, uMsg, pPsp);
  574. } // end PropSheetPageProc()
  575. void CDlgRASDialinMerge::OnChangeEditcallback()
  576. {
  577. // TODO: If this is a RICHEDIT control, the control will not
  578. // send this notification unless you override the CPropertyPage::OnInitDialog()
  579. // function to send the EM_SETEVENTMASK message to the control
  580. // with the ENM_CHANGE flag ORed into the lParam mask.
  581. // TODO: Add your control notification handler code here
  582. SetModified();
  583. }
  584. void CDlgRASDialinMerge::OnChangeEditcallerid()
  585. {
  586. SetModified();
  587. // TODO: If this is a RICHEDIT control, the control will not
  588. // send this notification unless you override the CPropertyPage::OnInitDialog()
  589. // function to send the EM_SETEVENTMASK message to the control
  590. // with the ENM_CHANGE flag ORed into the lParam mask.
  591. // TODO: Add your control notification handler code here
  592. }
  593. void CDlgRASDialinMerge::OnPermitAllow()
  594. {
  595. SetModified();
  596. }
  597. void CDlgRASDialinMerge::OnPermitDeny()
  598. {
  599. SetModified();
  600. }
  601. void CDlgRASDialinMerge::OnPermitPolicy()
  602. {
  603. SetModified();
  604. }
  605. void CDlgRASDialinMerge::OnFieldchangedEditipaddress(NMHDR* pNMHDR, LRESULT* pResult)
  606. {
  607. SetModified();
  608. *pResult = 0;
  609. }