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.

1172 lines
30 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. /*++
  3. Copyright (C) Microsoft Corporation, 1998 - 1999
  4. Module Name: AddPolicyWizardPage2.cpp
  5. Abstract:
  6. Implementation file for the CNewRAPWiz_Condition class.
  7. We implement the class needed to handle the first property page for a Policy node.
  8. Revision History:
  9. mmaguire 12/15/97 - created
  10. byao 1/22/98 Modified for Network Access Policy
  11. --*/
  12. //////////////////////////////////////////////////////////////////////////////
  13. #include "Precompiled.h"
  14. #include "rapwz_cond.h"
  15. #include "NapUtil.h"
  16. #include "PolicyNode.h"
  17. #include "PoliciesNode.h"
  18. #include "Condition.h"
  19. #include "EnumCondition.h"
  20. #include "MatchCondition.h"
  21. #include "TodCondition.h"
  22. #include "NtGCond.h"
  23. #include "rasprof.h"
  24. #include "ChangeNotification.h"
  25. //+---------------------------------------------------------------------------
  26. //
  27. // Function: CNewRAPWiz_Condition
  28. //
  29. // Class: CNewRAPWiz_Condition
  30. //
  31. // Synopsis: class constructor
  32. //
  33. // Arguments: CPolicyNode *pPolicyNode - policy node for this property page
  34. // CIASAttrList *pAttrList -- attribute list
  35. // TCHAR* pTitle = NULL -
  36. //
  37. // Returns: Nothing
  38. //
  39. // History: Created Header byao 2/16/98 4:31:52 PM
  40. //
  41. //+---------------------------------------------------------------------------
  42. CNewRAPWiz_Condition::CNewRAPWiz_Condition(
  43. CRapWizardData* pWizData,
  44. LONG_PTR hNotificationHandle,
  45. CIASAttrList *pIASAttrList,
  46. TCHAR* pTitle, BOOL bOwnsNotificationHandle
  47. )
  48. : CIASWizard97Page<CNewRAPWiz_Condition, IDS_NEWRAPWIZ_CONDITION_TITLE, IDS_NEWRAPWIZ_CONDITION_SUBTITLE> ( hNotificationHandle, pTitle, bOwnsNotificationHandle ),
  49. m_spWizData(pWizData)
  50. {
  51. TRACE_FUNCTION("CNewRAPWiz_Condition::CNewRAPWiz_Condition");
  52. m_pIASAttrList = pIASAttrList;
  53. }
  54. //+---------------------------------------------------------------------------
  55. //
  56. // Function: CNewRAPWiz_Condition
  57. //
  58. // Class: CNewRAPWiz_Condition
  59. //
  60. // Synopsis: class destructor
  61. //
  62. // Returns: Nothing
  63. //
  64. // History: Created Header byao 2/16/98 4:31:52 PM
  65. //
  66. //+---------------------------------------------------------------------------
  67. CNewRAPWiz_Condition::~CNewRAPWiz_Condition()
  68. {
  69. TRACE_FUNCTION("CNewRAPWiz_Condition::~CNewRAPWiz_Condition");
  70. CCondition* pCondition;
  71. // delete all the conditions in the list
  72. for (int iIndex=0; iIndex<m_ConditionList.GetSize(); iIndex++)
  73. {
  74. pCondition = m_ConditionList[iIndex];
  75. if ( pCondition )
  76. {
  77. delete pCondition;
  78. }
  79. }
  80. m_ConditionList.RemoveAll();
  81. }
  82. //////////////////////////////////////////////////////////////////////////////
  83. /*++
  84. CNewRAPWiz_Condition::OnInitDialog
  85. --*/
  86. //////////////////////////////////////////////////////////////////////////////
  87. LRESULT CNewRAPWiz_Condition::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  88. {
  89. TRACE_FUNCTION("CNewRAPWiz_Condition::OnInitDialog");
  90. HRESULT hr = S_OK;
  91. BOOL fRet;
  92. CComPtr<IUnknown> spUnknown;
  93. CComPtr<IEnumVARIANT> spEnumVariant;
  94. long ulCount;
  95. ULONG ulCountReceived;
  96. fRet = GetSdoPointers();
  97. if (!fRet)
  98. {
  99. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "GetSdoPointers() failed, err = %x", GetLastError());
  100. return fRet;
  101. }
  102. //
  103. // initialize the condition attribute list
  104. //
  105. hr = m_pIASAttrList->Init(m_spWizData->m_spDictionarySdo);
  106. if ( FAILED(hr) )
  107. {
  108. // Inside Init() there're already error reporting
  109. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "m_pIASAttrList->Init() failed, err = %x", hr);
  110. return FALSE;
  111. }
  112. if (m_ConditionList.GetSize() == 0)
  113. {
  114. //get the condition collection for this SDO
  115. m_spConditionCollectionSdo = NULL;
  116. hr = ::GetSdoInterfaceProperty(
  117. m_spWizData->m_spPolicySdo,
  118. PROPERTY_POLICY_CONDITIONS_COLLECTION,
  119. IID_ISdoCollection,
  120. (void **)&m_spConditionCollectionSdo);
  121. if ( FAILED(hr) )
  122. {
  123. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "Can't get condition collection Sdo, err = %x", hr);
  124. return FALSE;
  125. }
  126. // how many conditions do we have for this policy right now?
  127. m_spConditionCollectionSdo->get_Count( & ulCount );
  128. DebugTrace(DEBUG_NAPMMC_POLICYPAGE1, "Number of conditions %d", ulCount);
  129. CComVariant varCond;
  130. CCondition *pCondition;
  131. if( ulCount > 0 )
  132. {
  133. //
  134. // Get the enumerator for the conditions collection.
  135. //
  136. hr = m_spConditionCollectionSdo->get__NewEnum( (IUnknown **) & spUnknown );
  137. if ( FAILED(hr) )
  138. {
  139. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "get__NewEnum() failed, err = %x", hr);
  140. ShowErrorDialog(m_hWnd, IDS_ERROR_SDO_ERROR_ENUMCOND, NULL, hr);
  141. return FALSE;
  142. }
  143. hr = spUnknown->QueryInterface( IID_IEnumVARIANT, (void **) &spEnumVariant );
  144. if ( FAILED(hr) )
  145. {
  146. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "QueryInterface(IEnumVARIANT) failed, err = %x", hr);
  147. ShowErrorDialog(m_hWnd, IDS_ERROR_SDO_ERROR_QUERYINTERFACE, NULL, hr);
  148. return FALSE;
  149. }
  150. _ASSERTE( spEnumVariant != NULL );
  151. spUnknown.Release();
  152. // Get the first item.
  153. hr = spEnumVariant->Next( 1, &varCond, &ulCountReceived );
  154. while( SUCCEEDED( hr ) && ulCountReceived == 1 )
  155. {
  156. // Get an sdo pointer from the variant we received.
  157. _ASSERTE( V_VT(&varCond) == VT_DISPATCH );
  158. _ASSERTE( V_DISPATCH(&varCond) != NULL );
  159. CComPtr<ISdo> spConditionSdo;
  160. hr = varCond.pdispVal->QueryInterface( IID_ISdo, (void **) &spConditionSdo );
  161. _ASSERTE( SUCCEEDED( hr ) );
  162. //
  163. // get condition text
  164. //
  165. CComVariant varCondProp;
  166. ATL::CString strCondText, strExternCondText, strCondAttr;
  167. ATTRIBUTEID AttrId;
  168. CONDITIONTYPE CondType;
  169. // get condition text -- with AttributeMatch, TimeOfDay, NTMembership
  170. // prefix strings
  171. hr = spConditionSdo->GetProperty(PROPERTY_CONDITION_TEXT,
  172. &varCondProp);
  173. if ( FAILED(hr) )
  174. {
  175. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "Can't get condition text, err = %x", hr);
  176. ShowErrorDialog(m_hWnd,
  177. IDS_ERROR_SDO_ERROR_GET_CONDTEXT,
  178. NULL,
  179. hr
  180. );
  181. return FALSE;
  182. }
  183. _ASSERTE( V_VT(&varCondProp) == VT_BSTR);
  184. strExternCondText = V_BSTR(&varCondProp);
  185. DebugTrace(DEBUG_NAPMMC_POLICYPAGE1, "ConditionText: %ws",strExternCondText);
  186. // we are done with this condition sdo
  187. spConditionSdo.Release();
  188. varCondProp.Clear();
  189. // now we need to strip off the unnecessary prefix string in
  190. // the condition text
  191. hr = StripCondTextPrefix(
  192. strExternCondText,
  193. strCondText,
  194. strCondAttr,
  195. &CondType
  196. );
  197. if ( FAILED(hr) )
  198. {
  199. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1,"StripCondTextPrefix() failed, err = %x", hr);
  200. ShowErrorDialog(m_hWnd,
  201. IDS_ERROR_INVALID_COND_SYNTAX,
  202. m_spWizData->m_pPolicyNode->m_bstrDisplayName
  203. );
  204. // go to the next condition
  205. varCond.Clear();
  206. hr = spEnumVariant->Next( 1, &varCond, &ulCountReceived );
  207. continue;
  208. }
  209. DebugTrace(DEBUG_NAPMMC_POLICYPAGE1,
  210. "ConditionText: %ws, CondAttr: %ws, CondType: %d",
  211. strCondText,
  212. strCondAttr,
  213. (int)CondType
  214. );
  215. switch(CondType)
  216. {
  217. case IAS_TIMEOFDAY_CONDITION: AttrId = IAS_ATTRIBUTE_NP_TIME_OF_DAY; break;
  218. case IAS_NTGROUPS_CONDITION: AttrId = IAS_ATTRIBUTE_NTGROUPS; break;
  219. case IAS_MATCH_CONDITION: {
  220. BSTR bstrName = SysAllocString(strCondAttr);
  221. if ( bstrName == NULL )
  222. {
  223. ShowErrorDialog(m_hWnd,
  224. IDS_ERROR_CANT_CREATE_CONDATTR,
  225. (LPTSTR)(LPCTSTR)strCondAttr,
  226. hr
  227. );
  228. return FALSE;
  229. }
  230. hr = m_spWizData->m_spDictionarySdo->GetAttributeID(bstrName, &AttrId);
  231. if ( FAILED(hr) )
  232. {
  233. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "GetAttributeID() failed, err = %x", hr);
  234. ShowErrorDialog(m_hWnd,
  235. IDS_ERROR_SDO_ERROR_GETATTROD,
  236. bstrName,
  237. hr
  238. );
  239. SysFreeString(bstrName);
  240. return FALSE;
  241. }
  242. SysFreeString(bstrName);
  243. }
  244. break;
  245. }
  246. // GetAt can throw exceptions.
  247. try
  248. {
  249. //
  250. // find the condition attribute ID in the attribute list
  251. //
  252. int nAttrIndex = m_pIASAttrList->Find(AttrId);
  253. if (nAttrIndex == -1)
  254. {
  255. //
  256. // the attribute is not even found in the attribute list
  257. //
  258. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, " Can't find this condattr in the list");
  259. ShowErrorDialog(m_hWnd, IDS_ERROR_CANT_FIND_ATTR);
  260. return FALSE;
  261. }
  262. switch( AttrId )
  263. {
  264. case IAS_ATTRIBUTE_NP_TIME_OF_DAY:
  265. // time of day condition
  266. pCondition = (CCondition*) new CTodCondition(m_pIASAttrList->GetAt(nAttrIndex),
  267. strCondText
  268. );
  269. break;
  270. case IAS_ATTRIBUTE_NTGROUPS:
  271. // nt group condition
  272. pCondition = (CCondition*) new CNTGroupsCondition(m_pIASAttrList->GetAt(nAttrIndex),
  273. strCondText,
  274. m_hWnd,
  275. m_spWizData->m_pPolicyNode->m_pszServerAddress
  276. );
  277. break;
  278. default:
  279. {
  280. CComPtr<IIASAttributeInfo> spAttributeInfo = m_pIASAttrList->GetAt(nAttrIndex);
  281. _ASSERTE(spAttributeInfo);
  282. ATTRIBUTESYNTAX as;
  283. hr = spAttributeInfo->get_AttributeSyntax( &as );
  284. _ASSERTE( SUCCEEDED(hr) );
  285. if( as == IAS_SYNTAX_ENUMERATOR )
  286. {
  287. // enum-type condition
  288. CEnumCondition *pEnumCondition = new CEnumCondition(m_pIASAttrList->GetAt(nAttrIndex),
  289. strCondText
  290. );
  291. pCondition = pEnumCondition;
  292. }
  293. else
  294. {
  295. // match condition
  296. pCondition = (CCondition*) new CMatchCondition(m_pIASAttrList->GetAt(nAttrIndex),
  297. strCondText
  298. );
  299. }
  300. }
  301. break;
  302. } // switch
  303. // Add the newly created node to the list of Policys.
  304. m_ConditionList.Add(pCondition);
  305. // get the next condition
  306. varCond.Clear();
  307. hr = spEnumVariant->Next( 1, &varCond, &ulCountReceived );
  308. }
  309. catch(...)
  310. {
  311. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "Exception thrown while populating condition list");
  312. continue;
  313. }
  314. } // while
  315. } // if
  316. }
  317. hr = PopulateConditions();
  318. if ( FAILED(hr) )
  319. {
  320. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "PopulateConditions() returns %x", hr);
  321. return FALSE;
  322. }
  323. SetModified(FALSE);
  324. return TRUE; // ISSUE: what do we need to be returning here?
  325. }
  326. //////////////////////////////////////////////////////////////////////////////
  327. /*++
  328. CNewRAPWiz_Condition::OnConditionAdd
  329. --*/
  330. //////////////////////////////////////////////////////////////////////////////
  331. LRESULT CNewRAPWiz_Condition::OnConditionAdd(UINT uMsg, WPARAM wParam, HWND hWnd, BOOL& bHandled)
  332. {
  333. TRACE_FUNCTION("CNewRAPWiz_Condition::OnConditionAdd");
  334. HRESULT hr = S_OK;
  335. CCondition *pCondition;
  336. // create the dialog box to select a condition attribute
  337. CSelCondAttrDlg * pSelCondAttrDlg = new CSelCondAttrDlg(m_pIASAttrList);
  338. if (NULL == pSelCondAttrDlg)
  339. {
  340. hr = HRESULT_FROM_WIN32(GetLastError());
  341. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "Can't create the CSelCondAttrDlg, err = %x", hr);
  342. ShowErrorDialog(m_hWnd, IDS_ERROR_CANT_CREATE_OBJECT, NULL, hr);
  343. return hr;
  344. }
  345. // Put up the dialog.
  346. int iResult = pSelCondAttrDlg -> DoModal();
  347. // The pSelCondAttrDlg->DoModal call returns TRUE if the user selected something.
  348. if( iResult && pSelCondAttrDlg->m_nSelectedCondAttr != -1)
  349. {
  350. //
  351. // The user selected something and chose OK -- create the condition object
  352. //
  353. IIASAttributeInfo* pSelectedAttr = m_pIASAttrList->GetAt(pSelCondAttrDlg->m_nSelectedCondAttr);
  354. ATTRIBUTEID id;
  355. pSelectedAttr->get_AttributeID( &id );
  356. switch( id )
  357. {
  358. case IAS_ATTRIBUTE_NP_TIME_OF_DAY:
  359. // time of day condition
  360. pCondition = (CCondition*) new CTodCondition(pSelectedAttr);
  361. break;
  362. case IAS_ATTRIBUTE_NTGROUPS :
  363. // nt group condition
  364. pCondition = (CCondition*) new CNTGroupsCondition(
  365. pSelectedAttr,
  366. m_hWnd,
  367. m_spWizData->m_pPolicyNode->m_pszServerAddress
  368. );
  369. break;
  370. default:
  371. //
  372. // is this attribute an enumerator?
  373. //
  374. ATTRIBUTESYNTAX as;
  375. pSelectedAttr->get_AttributeSyntax( &as );
  376. if ( as == IAS_SYNTAX_ENUMERATOR )
  377. {
  378. // enum-type condition
  379. CEnumCondition *pEnumCondition = new CEnumCondition(pSelectedAttr);
  380. pCondition = pEnumCondition;
  381. }
  382. else
  383. {
  384. // match condition
  385. pCondition = (CCondition*) new CMatchCondition(pSelectedAttr);
  386. }
  387. break;
  388. } // switch
  389. if ( pCondition==NULL)
  390. {
  391. hr = E_OUTOFMEMORY;
  392. ShowErrorDialog(m_hWnd, IDS_ERROR_CANT_CREATE_COND, NULL, hr);
  393. goto failure;
  394. }
  395. //
  396. // now edit the condition
  397. //
  398. hr = pCondition->Edit();
  399. if ( FAILED(hr) )
  400. {
  401. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "pCondition->Edit() returns %x", hr);
  402. return hr;
  403. }
  404. // if the condition text is empty, then do nothing
  405. if ( pCondition->m_strConditionText.GetLength() == 0)
  406. {
  407. delete pSelCondAttrDlg;
  408. delete pCondition;
  409. return S_OK;
  410. }
  411. //
  412. // now, update the UI: add the new condition to the listbox
  413. //
  414. if (m_ConditionList.GetSize())
  415. {
  416. // before we do that, add an "AND" to the current last condition
  417. ATL::CString strDispCondText;
  418. SendDlgItemMessage( IDC_LIST_POLICYPAGE1_CONDITIONS,
  419. LB_DELETESTRING,
  420. m_ConditionList.GetSize()-1,
  421. 0L);
  422. strDispCondText = m_ConditionList[m_ConditionList.GetSize()-1]->GetDisplayText() + _T(" AND");
  423. SendDlgItemMessage( IDC_LIST_POLICYPAGE1_CONDITIONS,
  424. LB_ADDSTRING,
  425. 0,
  426. (LPARAM)(LPCTSTR)strDispCondText);
  427. }
  428. SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS,
  429. LB_ADDSTRING,
  430. 0,
  431. (LPARAM)(LPCTSTR)pCondition->GetDisplayText());
  432. SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS,
  433. LB_SETCURSEL,
  434. SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS, LB_GETCOUNT, 0,0L)-1,
  435. (LPARAM)(LPCTSTR)pCondition->GetDisplayText());
  436. ::EnableWindow(GetDlgItem(IDC_BUTTON_CONDITION_REMOVE), TRUE);
  437. ::EnableWindow(GetDlgItem(IDC_BUTTON_CONDITION_EDIT), TRUE);
  438. //
  439. // add this condition to the condition list
  440. //
  441. m_ConditionList.Add((CCondition*)pCondition);
  442. // set the dirty bit
  443. SetModified(TRUE);
  444. } // if // iResult
  445. delete pSelCondAttrDlg;
  446. AdjustHoritontalScroll();
  447. return TRUE; // ISSUE: what do we need to be returning here?
  448. failure:
  449. if (pSelCondAttrDlg)
  450. {
  451. delete pSelCondAttrDlg;
  452. }
  453. if (pCondition)
  454. {
  455. delete pCondition;
  456. }
  457. return hr;
  458. }
  459. //////////////////////////////////////////////////////////////////////////////
  460. /*++
  461. CNewRAPWiz_Condition::OnWizardNext
  462. --*/
  463. //////////////////////////////////////////////////////////////////////////////
  464. BOOL CNewRAPWiz_Condition::OnWizardNext()
  465. {
  466. TRACE_FUNCTION("CNewRAPWiz_Condition::OnWizardNext");
  467. HRESULT hr = S_OK;
  468. CPoliciesNode* pPoliciesNode = (CPoliciesNode*)m_spWizData->m_pPolicyNode->m_pParentNode;
  469. BOOL fRet = GetSdoPointers();
  470. if (!fRet)
  471. {
  472. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "GetSdoPointers() failed, err = %x", GetLastError());
  473. return FALSE;
  474. }
  475. //
  476. // do we have any conditions for this policy?
  477. // We don't allow policy with no conditions
  478. //
  479. if ( ! m_ConditionList.GetSize() )
  480. {
  481. ErrorTrace(DEBUG_NAPMMC_POLICYPAGE1, "The policy has no condition");
  482. ShowErrorDialog(m_hWnd
  483. , IDS_ERROR_ZERO_CONDITION_POLICY
  484. , NULL
  485. );
  486. return FALSE;
  487. }
  488. // Save the conditions to the SDO
  489. hr = WriteConditionListToSDO( m_ConditionList, m_spConditionCollectionSdo, m_hWnd );
  490. if( FAILED( hr ) )
  491. {
  492. // We output an error message in the function.
  493. return FALSE;
  494. }
  495. // reset the dirty bit
  496. SetModified(FALSE);
  497. return m_spWizData->GetNextPageId(((PROPSHEETPAGE*)(*this))->pszTemplate);
  498. }
  499. //////////////////////////////////////////////////////////////////////////////
  500. /*++
  501. CNewRAPWiz_Condition::OnQueryCancel
  502. --*/
  503. //////////////////////////////////////////////////////////////////////////////
  504. BOOL CNewRAPWiz_Condition::OnQueryCancel()
  505. {
  506. TRACE_FUNCTION("CNewRAPWiz_Condition::OnQueryCancel");
  507. return TRUE;
  508. }
  509. //+---------------------------------------------------------------------------
  510. //
  511. // Function: PopulateConditions
  512. //
  513. // Class: CNewRAPWiz_Condition
  514. //
  515. // Synopsis: populate the conditions for a particular policy
  516. //
  517. // Arguments: None
  518. //
  519. // Returns: HRESULT - S_OK: succeed
  520. // S_FALSE : if failed
  521. //
  522. // History: Created byao 2/2/98 4:01:26 PM
  523. //
  524. //+---------------------------------------------------------------------------
  525. HRESULT CNewRAPWiz_Condition::PopulateConditions()
  526. {
  527. TRACE_FUNCTION("CNewRAPWiz_Condition::PopulateConditions");
  528. SendDlgItemMessage( IDC_LIST_POLICYPAGE1_CONDITIONS,
  529. LB_RESETCONTENT,
  530. 0,
  531. 0L
  532. );
  533. ATL::CString strDispCondText;
  534. for (int iIndex=0; iIndex<m_ConditionList.GetSize(); iIndex++)
  535. {
  536. strDispCondText = m_ConditionList[iIndex]->GetDisplayText();
  537. if ( iIndex != m_ConditionList.GetSize()-1 )
  538. {
  539. // it's not the last condition, then we put an 'AND' at the
  540. // end of the condition text
  541. strDispCondText += " AND";
  542. }
  543. // display it
  544. SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS,
  545. LB_ADDSTRING,
  546. 0,
  547. (LPARAM)(LPCTSTR)strDispCondText);
  548. }
  549. if ( m_ConditionList.GetSize() == 0)
  550. {
  551. // no condition, then disable "Remove" and "Edit"
  552. ::EnableWindow(GetDlgItem(IDC_BUTTON_CONDITION_REMOVE), FALSE);
  553. ::EnableWindow(GetDlgItem(IDC_BUTTON_CONDITION_EDIT), FALSE);
  554. }
  555. else
  556. {
  557. SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS, LB_SETCURSEL, 0, 0L);
  558. ::EnableWindow(GetDlgItem(IDC_BUTTON_CONDITION_EDIT), TRUE);
  559. ::EnableWindow(GetDlgItem(IDC_BUTTON_CONDITION_REMOVE), TRUE);
  560. }
  561. AdjustHoritontalScroll();
  562. return S_OK;
  563. }
  564. //+---------------------------------------------------------------------------
  565. //
  566. // Function: OnConditionList
  567. //
  568. // Class: CConditionPage1
  569. //
  570. // Synopsis: message handler for the condition list box
  571. //
  572. // Arguments: UINT uNotifyCode - notification code
  573. // UINT uID - ID of the control
  574. // HWND hWnd - HANDLE of the window
  575. // BOOL &bHandled - whether the handler has processed the msg
  576. //
  577. // Returns: LRESULT - S_OK: succeeded
  578. // S_FALSE: otherwise
  579. //
  580. // History: Created byao 2/2/98 4:51:35 PM
  581. //
  582. //+---------------------------------------------------------------------------
  583. LRESULT CNewRAPWiz_Condition::OnConditionList(UINT uNotifyCode, UINT uID, HWND hWnd, BOOL &bHandled)
  584. {
  585. TRACE_FUNCTION("CNewRAPWiz_Condition::OnConditionList");
  586. if (uNotifyCode == LBN_DBLCLK)
  587. {
  588. // edit the condition
  589. OnConditionEdit(uNotifyCode, uID, hWnd, bHandled);
  590. }
  591. return S_OK;
  592. }
  593. //+---------------------------------------------------------------------------
  594. //
  595. // Function: OnConditionEdit
  596. //
  597. // Class: CConditionPage1
  598. //
  599. // Synopsis: message handler for the condition list box -- user pressed the Edit button
  600. // we need to edit a particular condition
  601. //
  602. // Arguments: UINT uNotifyCode - notification code
  603. // UINT uID - ID of the control
  604. // HWND hWnd - HANDLE of the window
  605. // BOOL &bHandled - whether the handler has processed the msg
  606. //
  607. // Returns: LRESULT - S_OK: succeeded
  608. // S_FALSE: otherwise
  609. //
  610. // History: Created byao 2/21/98 4:51:35 PM
  611. //
  612. //+---------------------------------------------------------------------------
  613. LRESULT CNewRAPWiz_Condition::OnConditionEdit(UINT uNotifyCode, UINT uID, HWND hWnd, BOOL &bHandled)
  614. {
  615. TRACE_FUNCTION("CNewRAPWiz_Condition::OnConditionEdit");
  616. LRESULT lRes, lCurSel;
  617. //
  618. // Has the user selected someone from the condition list?
  619. //
  620. lCurSel = SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS,
  621. LB_GETCURSEL,
  622. 0,
  623. 0L);
  624. if (lCurSel == LB_ERR)
  625. {
  626. // no selection -- do nothing
  627. bHandled = TRUE;
  628. return S_OK;
  629. }
  630. //
  631. // Edit the condition
  632. //
  633. CCondition *pCondition = m_ConditionList[lCurSel];
  634. HRESULT hr = pCondition->Edit();
  635. //
  636. // change the displayed condition text
  637. //
  638. // is this the last condition?
  639. ATL::CString strDispCondText = m_ConditionList[lCurSel]->GetDisplayText();
  640. if ( lCurSel != m_ConditionList.GetSize()-1 )
  641. {
  642. // put an extra 'AND' at the end
  643. strDispCondText += _T(" AND");
  644. }
  645. // replace it with new
  646. lRes = SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS,
  647. LB_INSERTSTRING,
  648. lCurSel,
  649. (LPARAM)(LPCTSTR)strDispCondText);
  650. // delete the old text
  651. lRes = SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS,
  652. LB_DELETESTRING,
  653. lCurSel+1,
  654. 0L);
  655. // set the dirty bit
  656. SetModified(TRUE);
  657. bHandled = TRUE;
  658. AdjustHoritontalScroll();
  659. return hr;
  660. }
  661. //+---------------------------------------------------------------------------
  662. //
  663. // Function: OnConditionRemove
  664. //
  665. // Class: CConditionPage1
  666. //
  667. // Synopsis: message handler for the condition list box -- user pressed "Remove"
  668. // we need to remove this condition
  669. //
  670. // Arguments: UINT uNotifyCode - notification code
  671. // UINT uID - ID of the control
  672. // HWND hWnd - HANDLE of the window
  673. // BOOL &bHandled - whether the handler has processed the msg
  674. //
  675. // Returns: LRESULT - S_OK: succeeded
  676. // S_FALSE: otherwise
  677. //
  678. // History: Created byao 2/22/98 4:51:35 PM
  679. //
  680. //+---------------------------------------------------------------------------
  681. LRESULT CNewRAPWiz_Condition::OnConditionRemove(UINT uMsg, WPARAM wParam, HWND hWnd, BOOL& bHandled)
  682. {
  683. TRACE_FUNCTION("CNewRAPWiz_Condition::OnConditionRemove");
  684. LRESULT lCurSel;
  685. HRESULT hr;
  686. //
  687. // Has the user selected someone from the condition list?
  688. //
  689. lCurSel = SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS,
  690. LB_GETCURSEL,
  691. 0,
  692. 0L);
  693. if (lCurSel == LB_ERR)
  694. {
  695. //
  696. // no selection -- do nothing
  697. //
  698. bHandled = TRUE;
  699. return S_OK;
  700. }
  701. // check whether this is the last one in the list.
  702. // if it is, we also need to delete the " AND" operator from
  703. // the next-to-last item
  704. if ( lCurSel!=0 && lCurSel == m_ConditionList.GetSize()-1 )
  705. {
  706. // delete the old one with an " AND"
  707. hr = SendDlgItemMessage( IDC_LIST_POLICYPAGE1_CONDITIONS,
  708. LB_DELETESTRING,
  709. lCurSel-1,
  710. 0L
  711. );
  712. // insert the one without 'AND"
  713. hr = SendDlgItemMessage( IDC_LIST_POLICYPAGE1_CONDITIONS,
  714. LB_INSERTSTRING,
  715. lCurSel-1,
  716. (LPARAM)(LPCTSTR)m_ConditionList[lCurSel-1]->GetDisplayText());
  717. }
  718. // delete the condition
  719. CCondition *pCondition = m_ConditionList[lCurSel];
  720. m_ConditionList.Remove(pCondition);
  721. delete pCondition;
  722. // delete the old text
  723. hr = SendDlgItemMessage( IDC_LIST_POLICYPAGE1_CONDITIONS,
  724. LB_DELETESTRING,
  725. lCurSel,
  726. 0L);
  727. bHandled = TRUE;
  728. // set the dirty bit
  729. SetModified(TRUE);
  730. if ( m_ConditionList.GetSize() == 0)
  731. {
  732. // no condition, then disable "Remove" and "Edit"
  733. ::EnableWindow(GetDlgItem(IDC_BUTTON_CONDITION_REMOVE), FALSE);
  734. ::EnableWindow(GetDlgItem(IDC_BUTTON_CONDITION_EDIT), FALSE);
  735. }
  736. else
  737. {
  738. // re-select another condition
  739. if ( lCurSel > 0 )
  740. {
  741. lCurSel--;
  742. }
  743. SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS, LB_SETCURSEL, lCurSel, 0L);
  744. }
  745. //
  746. // adjust the scroll bar
  747. //
  748. AdjustHoritontalScroll();
  749. return hr;
  750. }
  751. //+---------------------------------------------------------------------------
  752. //
  753. // Function: CNewRAPWiz_Condition::GetSdoPointers
  754. //
  755. // Synopsis: UnMarshall all passed in sdo pointers. These interface pointers
  756. // have to be unmarshalled first, because MMC PropertyPages run in a
  757. // separated thread
  758. //
  759. // Also get the condition collection sdo from the policy sdo
  760. //
  761. // Arguments: None
  762. //
  763. // Returns: TRUE; succeeded
  764. // FALSE: otherwise
  765. //
  766. // History: Created Header byao 2/22/98 1:35:39 AM
  767. //
  768. //+---------------------------------------------------------------------------
  769. BOOL CNewRAPWiz_Condition::GetSdoPointers()
  770. {
  771. TRACE_FUNCTION("CNewRAPWiz_Condition::GetSdoPointers");
  772. HRESULT hr;
  773. // Get the condition collection of this SDO.
  774. if ( m_spWizData->m_spPolicySdo )
  775. {
  776. if ( m_spConditionCollectionSdo )
  777. {
  778. m_spConditionCollectionSdo.Release();
  779. m_spConditionCollectionSdo = NULL;
  780. }
  781. hr = ::GetSdoInterfaceProperty(
  782. m_spWizData->m_spPolicySdo,
  783. PROPERTY_POLICY_CONDITIONS_COLLECTION,
  784. IID_ISdoCollection,
  785. (void **) &m_spConditionCollectionSdo);
  786. if( FAILED( hr) || m_spConditionCollectionSdo == NULL )
  787. {
  788. ShowErrorDialog(m_hWnd,
  789. IDS_ERROR_UNMARSHALL,
  790. NULL,
  791. hr
  792. );
  793. return FALSE;
  794. }
  795. }
  796. return TRUE;
  797. }
  798. //+---------------------------------------------------------------------------
  799. //
  800. // Function: CNewRAPWiz_Condition::StripCondTextPrefix
  801. //
  802. // Synopsis: strip off the prefix such as "AttributeMatch", "TimeOfDay", NtMemberShip"
  803. // from the condition text
  804. //
  805. // Arguments:
  806. // [in]CString strExternCondText -- original condition text
  807. // [out]CString strCondText -- stripped condition text
  808. // [out]CString strCondAttr -- condition attribute name
  809. // [out]CONDITIONTYPE* pCondType -- what type of condition?
  810. //
  811. // Returns: HRESULT -
  812. //
  813. // History: Created Header byao 2/27/98 3:59:38 PM
  814. //
  815. //+---------------------------------------------------------------------------
  816. HRESULT CNewRAPWiz_Condition::StripCondTextPrefix(
  817. ATL::CString& strExternCondText,
  818. ATL::CString& strCondText,
  819. ATL::CString& strCondAttr,
  820. CONDITIONTYPE* pCondType
  821. )
  822. {
  823. TRACE_FUNCTION("CNewRAPWiz_Condition::StripCondTextPrefix");
  824. HRESULT hr = S_OK;
  825. // is it an empty string
  826. if ( strExternCondText.GetLength() == 0 )
  827. {
  828. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1,"Can't parse prefix: empty condition text");
  829. return E_INVALIDARG;
  830. }
  831. // a temporary copy
  832. ATL::CString strTempStr = (LPCTSTR)strExternCondText;
  833. WCHAR *pwzCondText = (WCHAR*)(LPCTSTR)strTempStr;
  834. strCondAttr = _T("");
  835. strCondText = _T("");
  836. // condition text will look like : AttributeMatch("attr=<reg>")
  837. // strip off the "AttributeMatch(" prefix
  838. WCHAR *pwzBeginCond = wcschr(pwzCondText, _T('('));
  839. WCHAR *pwzEndCond = wcsrchr(pwzCondText, _T(')'));
  840. if ( ( pwzBeginCond == NULL ) || ( pwzEndCond == NULL ) )
  841. {
  842. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1,"Can't parse prefix: no ( or ) found");
  843. return E_INVALIDARG;
  844. }
  845. //
  846. // now we should decide what kind of condition this is:
  847. //
  848. *pwzBeginCond = _T('\0');
  849. DebugTrace(DEBUG_NAPMMC_POLICYPAGE1, "ConditionType: %ws", pwzCondText);
  850. if ( _wcsicmp(pwzCondText, TOD_PREFIX) == 0 )
  851. {
  852. *pCondType = IAS_TIMEOFDAY_CONDITION;
  853. }
  854. else if ( _wcsicmp(pwzCondText, NTG_PREFIX) == 0 )
  855. {
  856. *pCondType = IAS_NTGROUPS_CONDITION;
  857. }
  858. else if ( _wcsicmp(pwzCondText, MATCH_PREFIX ) == 0 )
  859. {
  860. *pCondType = IAS_MATCH_CONDITION;
  861. }
  862. else
  863. {
  864. return E_INVALIDARG;
  865. }
  866. // skip the '(' sign
  867. pwzBeginCond += 2 ;
  868. // skip the ')' sign
  869. *(pwzEndCond-1) = _T('\0');
  870. // So right now the string between pwzBeginCond and pwzEndCond is the
  871. // real condition text
  872. strCondText = pwzBeginCond;
  873. if ( IAS_MATCH_CONDITION == *pCondType )
  874. {
  875. // for match-type condition, we need to get the condition attribute name
  876. WCHAR *pwzEqualSign = wcschr(pwzBeginCond, _T('='));
  877. if ( pwzEqualSign == NULL )
  878. {
  879. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "Can't parse : there's no = found");
  880. return E_INVALIDARG;
  881. }
  882. *pwzEqualSign = _T('\0');
  883. strCondAttr = pwzBeginCond;
  884. }
  885. else
  886. {
  887. strCondAttr = _T("");
  888. }
  889. DebugTrace(DEBUG_NAPMMC_POLICYPAGE1, "Condition Attr: %ws", strCondAttr);
  890. return S_OK;
  891. }
  892. //+---------------------------------------------------------------------------
  893. //
  894. // Function: AdjustHoritontalScroll
  895. //
  896. // Class: CConditionPage1
  897. //
  898. // Synopsis: message handler for the condition list box
  899. //
  900. // History: Created byao 2/2/98 4:51:35 PM
  901. //
  902. //+---------------------------------------------------------------------------
  903. void CNewRAPWiz_Condition::AdjustHoritontalScroll()
  904. {
  905. TRACE_FUNCTION("CNewRAPWiz_Condition::AdjustHorizontalScroll()");
  906. //
  907. // According to the maximum length of all list box items,
  908. // set the horizontal scrolling range
  909. //
  910. HDC hDC = ::GetDC(GetDlgItem(IDC_LIST_POLICYPAGE1_CONDITIONS));
  911. int iItemCount = m_ConditionList.GetSize();
  912. int iMaxLength = 0;
  913. for (int iIndex=0; iIndex<iItemCount; iIndex++)
  914. {
  915. ATL::CString strCondText;
  916. strCondText = m_ConditionList[iIndex]->GetDisplayText();
  917. SIZE szText;
  918. if ( GetTextExtentPoint32(hDC, (LPCTSTR)strCondText, strCondText.GetLength(), &szText) )
  919. {
  920. DebugTrace(DEBUG_NAPMMC_POLICYPAGE1,
  921. "Condition: %ws, Length %d, PixelSize %d",
  922. (LPCTSTR)strCondText,
  923. strCondText.GetLength(),
  924. szText.cx
  925. );
  926. if (iMaxLength < szText.cx )
  927. {
  928. iMaxLength = szText.cx;
  929. }
  930. }
  931. DebugTrace(DEBUG_NAPMMC_POLICYPAGE1, "Maximum item length is %d", iMaxLength);
  932. }
  933. SendDlgItemMessage( IDC_LIST_POLICYPAGE1_CONDITIONS,
  934. LB_SETHORIZONTALEXTENT,
  935. iMaxLength,
  936. 0L);
  937. }
  938. //////////////////////////////////////////////////////////////////////////////
  939. /*++
  940. CNewRAPWiz_Condition::OnSetActive
  941. Return values:
  942. TRUE if the page can be made active
  943. FALSE if the page should be be skipped and the next page should be looked at.
  944. Remarks:
  945. If you want to change which pages are visited based on a user's
  946. choices in a previous page, return FALSE here as appropriate.
  947. --*/
  948. //////////////////////////////////////////////////////////////////////////////
  949. BOOL CNewRAPWiz_Condition::OnSetActive()
  950. {
  951. ATLTRACE(_T("# CNewRAPWiz_Condition::OnSetActive\n"));
  952. // MSDN docs say you need to use PostMessage here rather than SendMessage.
  953. ::PropSheet_SetWizButtons(GetParent(), PSWIZB_BACK | PSWIZB_NEXT );
  954. return TRUE;
  955. }