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.

1023 lines
30 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // condlist.cpp
  8. //
  9. // SYNOPSIS
  10. //
  11. // Defines the class ConditionList.
  12. //
  13. // MODIFICATION HISTORY
  14. //
  15. // 03/01/2000 Original version.
  16. //
  17. ///////////////////////////////////////////////////////////////////////////////
  18. #include <precompiled.h>
  19. #include <condlist.h>
  20. #include <condition.h>
  21. #include <iasattrlist.h>
  22. #include <enumcondition.h>
  23. #include <matchcondition.h>
  24. #include <todcondition.h>
  25. #include <ntgcond.h>
  26. #include <selcondattr.h>
  27. CIASAttrList*
  28. WINAPI
  29. CreateCIASAttrList() throw ()
  30. {
  31. return new CIASAttrList();
  32. }
  33. VOID
  34. WINAPI
  35. DestroyCIASAttrList(CIASAttrList* attrList) throw ()
  36. {
  37. delete attrList;
  38. }
  39. PVOID
  40. WINAPI
  41. ExtractCIASAttrList(CIASAttrList* attrList) throw ()
  42. {
  43. return &attrList->m_AttrList;
  44. }
  45. #define SetModified(x) modified = x
  46. ConditionList::~ConditionList() throw ()
  47. {
  48. clear();
  49. }
  50. void ConditionList::finalConstruct(
  51. HWND dialog,
  52. CIASAttrList* attrList,
  53. LONG attrFilter,
  54. ISdoDictionaryOld* dnary,
  55. ISdoCollection* conditions,
  56. PCWSTR machineName,
  57. PCWSTR policyName
  58. ) throw ()
  59. {
  60. m_hWnd = dialog;
  61. m_pIASAttrList = attrList;
  62. m_filter = attrFilter;
  63. m_spDictionarySdo = dnary;
  64. m_spConditionCollectionSdo = conditions;
  65. m_pPolicyNode->m_bstrDisplayName = const_cast<PWSTR>(policyName);
  66. m_pPolicyNode->m_pszServerAddress = const_cast<PWSTR>(machineName);
  67. }
  68. void ConditionList::clear()
  69. {
  70. for (int i = 0; i < m_ConditionList.GetSize(); ++i)
  71. {
  72. delete m_ConditionList[i];
  73. }
  74. m_ConditionList.RemoveAll();
  75. }
  76. ::CString ConditionList::getDisplayText()
  77. {
  78. CreateConditions();
  79. ::CString text;
  80. for (int i = 0; i < m_ConditionList.GetSize(); ++i)
  81. {
  82. text += L" ";
  83. text += m_ConditionList[i]->GetDisplayText();
  84. if (i != m_ConditionList.GetSize() - 1)
  85. {
  86. // it's not the last condition, then we put an 'AND' at the
  87. // end of the condition text
  88. text += L" AND\n";
  89. }
  90. }
  91. return text;
  92. }
  93. HRESULT StripCondTextPrefix(
  94. ATL::CString& strExternCondText,
  95. ATL::CString& strCondText,
  96. ATL::CString& strCondAttr,
  97. CONDITIONTYPE* pdwCondType
  98. );
  99. BOOL ConditionList::onInitDialog()
  100. {
  101. if (!CreateConditions()) { return FALSE; }
  102. HRESULT hr = PopulateConditions();
  103. if ( FAILED(hr) )
  104. {
  105. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "PopulateConditions() returns %x", hr);
  106. return FALSE;
  107. }
  108. return TRUE; // ISSUE: what do we need to be returning here?
  109. }
  110. BOOL ConditionList::onApply()
  111. {
  112. HRESULT hr = S_OK;
  113. int iIndex;
  114. //
  115. // do we have any conditions for this policy?
  116. // We don't allow policy with no conditions
  117. //
  118. if ( ! m_ConditionList.GetSize() )
  119. {
  120. ErrorTrace(DEBUG_NAPMMC_POLICYPAGE1, "The policy has no condition");
  121. ShowErrorDialog(m_hWnd
  122. , IDS_ERROR_ZERO_CONDITION_POLICY
  123. , NULL
  124. );
  125. return FALSE;
  126. }
  127. // Save the conditions to the SDO
  128. hr = WriteConditionListToSDO( m_ConditionList, m_spConditionCollectionSdo, m_hWnd );
  129. if( FAILED( hr ) )
  130. {
  131. // We output an error message in the function.
  132. return FALSE;
  133. }
  134. return TRUE;
  135. }
  136. HRESULT ConditionList::onAdd(BOOL& modified)
  137. {
  138. HRESULT hr = S_OK;
  139. CCondition *pCondition;
  140. // create the dialog box to select a condition attribute
  141. CSelCondAttrDlg * pSelCondAttrDlg = new CSelCondAttrDlg(m_pIASAttrList, m_filter);
  142. if (NULL == pSelCondAttrDlg)
  143. {
  144. hr = HRESULT_FROM_WIN32(GetLastError());
  145. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "Can't create the CSelCondAttrDlg, err = %x", hr);
  146. ShowErrorDialog(m_hWnd, IDS_ERROR_CANT_CREATE_OBJECT, NULL, hr);
  147. return hr;
  148. }
  149. // Put up the dialog.
  150. int iResult = pSelCondAttrDlg -> DoModal();
  151. // The pSelCondAttrDlg->DoModal call returns TRUE if the user selected something.
  152. if( iResult && pSelCondAttrDlg->m_nSelectedCondAttr != -1)
  153. {
  154. //
  155. // The user selected something and chose OK -- create the condition object
  156. //
  157. IIASAttributeInfo* pSelectedAttr = m_pIASAttrList->GetAt(pSelCondAttrDlg->m_nSelectedCondAttr);
  158. ATTRIBUTEID id;
  159. pSelectedAttr->get_AttributeID( &id );
  160. switch( id )
  161. {
  162. case IAS_ATTRIBUTE_NP_TIME_OF_DAY:
  163. // time of day condition
  164. pCondition = (CCondition*) new CTodCondition(pSelectedAttr);
  165. break;
  166. case IAS_ATTRIBUTE_NTGROUPS :
  167. // nt group condition
  168. pCondition = (CCondition*) new CNTGroupsCondition(
  169. pSelectedAttr,
  170. m_hWnd,
  171. m_pPolicyNode->m_pszServerAddress
  172. );
  173. break;
  174. default:
  175. //
  176. // is this attribute an enumerator?
  177. //
  178. ATTRIBUTESYNTAX as;
  179. pSelectedAttr->get_AttributeSyntax( &as );
  180. if ( as == IAS_SYNTAX_ENUMERATOR )
  181. {
  182. // enum-type condition
  183. CEnumCondition *pEnumCondition = new CEnumCondition(pSelectedAttr);
  184. pCondition = pEnumCondition;
  185. }
  186. else
  187. {
  188. // match condition
  189. pCondition = (CCondition*) new CMatchCondition(pSelectedAttr);
  190. }
  191. break;
  192. } // switch
  193. if ( pCondition==NULL)
  194. {
  195. hr = E_OUTOFMEMORY;
  196. ShowErrorDialog(m_hWnd, IDS_ERROR_CANT_CREATE_COND, NULL, hr);
  197. goto failure;
  198. }
  199. //
  200. // now edit the condition
  201. //
  202. hr = pCondition->Edit();
  203. if ( FAILED(hr) )
  204. {
  205. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "pCondition->Edit() returns %x", hr);
  206. return hr;
  207. }
  208. // if the condition text is empty, then do nothing
  209. if ( pCondition->m_strConditionText.GetLength() == 0)
  210. {
  211. delete pSelCondAttrDlg;
  212. delete pCondition;
  213. return S_OK;
  214. }
  215. //
  216. // now, update the UI: add the new condition to the listbox
  217. //
  218. if (m_ConditionList.GetSize())
  219. {
  220. // before we do that, add an "AND" to the current last condition
  221. ATL::CString strDispCondText;
  222. SendDlgItemMessage( IDC_LIST_POLICYPAGE1_CONDITIONS,
  223. LB_DELETESTRING,
  224. m_ConditionList.GetSize()-1,
  225. 0L);
  226. strDispCondText = m_ConditionList[m_ConditionList.GetSize()-1]->GetDisplayText() + _T(" AND");
  227. SendDlgItemMessage( IDC_LIST_POLICYPAGE1_CONDITIONS,
  228. LB_ADDSTRING,
  229. 0,
  230. (LPARAM)(LPCTSTR)strDispCondText);
  231. }
  232. SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS,
  233. LB_ADDSTRING,
  234. 0,
  235. (LPARAM)(LPCTSTR)pCondition->GetDisplayText());
  236. SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS,
  237. LB_SETCURSEL,
  238. SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS, LB_GETCOUNT, 0,0L)-1,
  239. (LPARAM)(LPCTSTR)pCondition->GetDisplayText());
  240. ::EnableWindow(GetDlgItem(IDC_BUTTON_CONDITION_REMOVE), TRUE);
  241. ::EnableWindow(GetDlgItem(IDC_BUTTON_CONDITION_EDIT), TRUE);
  242. //
  243. // add this condition to the condition list
  244. //
  245. m_ConditionList.Add((CCondition*)pCondition);
  246. // set the dirty bit
  247. SetModified(TRUE);
  248. } // if // iResult
  249. delete pSelCondAttrDlg;
  250. AdjustHoritontalScroll();
  251. return TRUE; // ISSUE: what do we need to be returning here?
  252. failure:
  253. if (pSelCondAttrDlg)
  254. {
  255. delete pSelCondAttrDlg;
  256. }
  257. if (pCondition)
  258. {
  259. delete pCondition;
  260. }
  261. return hr;
  262. }
  263. HRESULT ConditionList::onEdit(BOOL& modified, BOOL& bHandled)
  264. {
  265. LRESULT lRes, lCurSel;
  266. //
  267. // Has the user selected someone from the condition list?
  268. //
  269. lCurSel = SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS,
  270. LB_GETCURSEL,
  271. 0,
  272. 0L);
  273. if (lCurSel == LB_ERR)
  274. {
  275. // no selection -- do nothing
  276. bHandled = TRUE;
  277. return S_OK;
  278. }
  279. //
  280. // Edit the condition
  281. //
  282. CCondition *pCondition = m_ConditionList[lCurSel];
  283. HRESULT hr = pCondition->Edit();
  284. //
  285. // change the displayed condition text
  286. //
  287. // is this the last condition?
  288. ATL::CString strDispCondText = m_ConditionList[lCurSel]->GetDisplayText();
  289. if ( lCurSel != m_ConditionList.GetSize()-1 )
  290. {
  291. // put an extra 'AND' at the end
  292. strDispCondText += _T(" AND");
  293. }
  294. // replace it with new
  295. lRes = SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS,
  296. LB_INSERTSTRING,
  297. lCurSel,
  298. (LPARAM)(LPCTSTR)strDispCondText);
  299. // select the new one
  300. lRes = SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS,
  301. LB_SETCURSEL,
  302. lCurSel,
  303. (LPARAM)0);
  304. // delete the old text
  305. lRes = SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS,
  306. LB_DELETESTRING,
  307. lCurSel+1,
  308. 0L);
  309. // set the dirty bit
  310. SetModified(TRUE);
  311. bHandled = TRUE;
  312. AdjustHoritontalScroll();
  313. return hr;
  314. }
  315. HRESULT ConditionList::onRemove(BOOL& modified, BOOL& bHandled)
  316. {
  317. LRESULT lCurSel;
  318. HRESULT hr;
  319. //
  320. // Has the user selected someone from the condition list?
  321. //
  322. lCurSel = SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS,
  323. LB_GETCURSEL,
  324. 0,
  325. 0L);
  326. if (lCurSel == LB_ERR)
  327. {
  328. //
  329. // no selection -- do nothing
  330. //
  331. bHandled = TRUE;
  332. return S_OK;
  333. }
  334. // check whether this is the last one in the list.
  335. // if it is, we also need to delete the " AND" operator from
  336. // the next-to-last item
  337. if ( lCurSel!=0 && lCurSel == m_ConditionList.GetSize()-1 )
  338. {
  339. // delete the old one with an " AND"
  340. hr = SendDlgItemMessage( IDC_LIST_POLICYPAGE1_CONDITIONS,
  341. LB_DELETESTRING,
  342. lCurSel-1,
  343. 0L
  344. );
  345. // insert the one without 'AND"
  346. hr = SendDlgItemMessage( IDC_LIST_POLICYPAGE1_CONDITIONS,
  347. LB_INSERTSTRING,
  348. lCurSel-1,
  349. (LPARAM)(LPCTSTR)m_ConditionList[lCurSel-1]->GetDisplayText());
  350. }
  351. // delete the condition
  352. CCondition *pCondition = m_ConditionList[lCurSel];
  353. m_ConditionList.Remove(pCondition);
  354. delete pCondition;
  355. // delete the old text
  356. hr = SendDlgItemMessage( IDC_LIST_POLICYPAGE1_CONDITIONS,
  357. LB_DELETESTRING,
  358. lCurSel,
  359. 0L);
  360. bHandled = TRUE;
  361. // set the dirty bit
  362. SetModified(TRUE);
  363. if ( m_ConditionList.GetSize() == 0)
  364. {
  365. // no condition, then disable "Remove" and "Edit"
  366. ::EnableWindow(GetDlgItem(IDC_BUTTON_CONDITION_REMOVE), FALSE);
  367. ::EnableWindow(GetDlgItem(IDC_BUTTON_CONDITION_EDIT), FALSE);
  368. }
  369. else
  370. {
  371. // re-select another condition
  372. if ( lCurSel > 0 )
  373. {
  374. lCurSel--;
  375. }
  376. SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS, LB_SETCURSEL, lCurSel, 0L);
  377. }
  378. //
  379. // adjust the scroll bar
  380. //
  381. AdjustHoritontalScroll();
  382. return hr;
  383. }
  384. void ConditionList::AdjustHoritontalScroll()
  385. {
  386. //
  387. // According to the maximum length of all list box items,
  388. // set the horizontal scrolling range
  389. //
  390. HDC hDC = ::GetDC(GetDlgItem(IDC_LIST_POLICYPAGE1_CONDITIONS));
  391. int iItemCount = m_ConditionList.GetSize();
  392. int iMaxLength = 0;
  393. for (int iIndex=0; iIndex<iItemCount; iIndex++)
  394. {
  395. ATL::CString strCondText;
  396. strCondText = m_ConditionList[iIndex]->GetDisplayText();
  397. SIZE szText;
  398. if ( GetTextExtentPoint32(hDC, (LPCTSTR)strCondText, strCondText.GetLength(), &szText) )
  399. {
  400. DebugTrace(DEBUG_NAPMMC_POLICYPAGE1,
  401. "Condition: %ws, Length %d, PixelSize %d",
  402. (LPCTSTR)strCondText,
  403. strCondText.GetLength(),
  404. szText.cx
  405. );
  406. if (iMaxLength < szText.cx )
  407. {
  408. iMaxLength = szText.cx;
  409. }
  410. }
  411. DebugTrace(DEBUG_NAPMMC_POLICYPAGE1, "Maximum item length is %d", iMaxLength);
  412. }
  413. SendDlgItemMessage( IDC_LIST_POLICYPAGE1_CONDITIONS,
  414. LB_SETHORIZONTALEXTENT,
  415. iMaxLength,
  416. 0L);
  417. }
  418. BOOL ConditionList::CreateConditions()
  419. {
  420. HRESULT hr = S_OK;
  421. BOOL fRet;
  422. CComPtr<IUnknown> spUnknown;
  423. CComPtr<IEnumVARIANT> spEnumVariant;
  424. long ulCount;
  425. ULONG ulCountReceived;
  426. //
  427. // initialize the condition attribute list
  428. //
  429. hr = m_pIASAttrList->Init(m_spDictionarySdo);
  430. if ( FAILED(hr) )
  431. {
  432. // Inside Init() there're already error reporting
  433. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "m_pIASAttrList->Init() failed, err = %x", hr);
  434. return FALSE;
  435. }
  436. if (m_ConditionList.GetSize() == 0)
  437. {
  438. // how many conditions do we have for this policy right now?
  439. m_spConditionCollectionSdo->get_Count( & ulCount );
  440. DebugTrace(DEBUG_NAPMMC_POLICYPAGE1, "Number of conditions %d", ulCount);
  441. CComVariant varCond;
  442. CCondition *pCondition;
  443. if( ulCount > 0 )
  444. {
  445. //
  446. // Get the enumerator for the Clients collection.
  447. //
  448. hr = m_spConditionCollectionSdo->get__NewEnum( (IUnknown **) & spUnknown );
  449. if ( FAILED(hr) )
  450. {
  451. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "get__NewEnum() failed, err = %x", hr);
  452. ShowErrorDialog(m_hWnd, IDS_ERROR_SDO_ERROR_ENUMCOND, NULL, hr);
  453. return FALSE;
  454. }
  455. hr = spUnknown->QueryInterface( IID_IEnumVARIANT, (void **) &spEnumVariant );
  456. if ( FAILED(hr) )
  457. {
  458. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "QueryInterface(IEnumVARIANT) failed, err = %x", hr);
  459. ShowErrorDialog(m_hWnd, IDS_ERROR_SDO_ERROR_QUERYINTERFACE, NULL, hr);
  460. return FALSE;
  461. }
  462. _ASSERTE( spEnumVariant != NULL );
  463. spUnknown.Release();
  464. // Get the first item.
  465. hr = spEnumVariant->Next( 1, &varCond, &ulCountReceived );
  466. while( SUCCEEDED( hr ) && ulCountReceived == 1 )
  467. {
  468. // Get an sdo pointer from the variant we received.
  469. _ASSERTE( V_VT(&varCond) == VT_DISPATCH );
  470. _ASSERTE( V_DISPATCH(&varCond) != NULL );
  471. CComPtr<ISdo> spConditionSdo;
  472. hr = varCond.pdispVal->QueryInterface( IID_ISdo, (void **) &spConditionSdo );
  473. _ASSERTE( SUCCEEDED( hr ) );
  474. //
  475. // get condition text
  476. //
  477. CComVariant varCondProp;
  478. ATL::CString strCondText, strExternCondText, strCondAttr;
  479. ATTRIBUTEID AttrId;
  480. CONDITIONTYPE CondType;
  481. // get condition text -- with AttributeMatch, TimeOfDay, NTMembership
  482. // prefix strings
  483. hr = spConditionSdo->GetProperty(PROPERTY_CONDITION_TEXT,
  484. &varCondProp);
  485. if ( FAILED(hr) )
  486. {
  487. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "Can't get condition text, err = %x", hr);
  488. ShowErrorDialog(m_hWnd,
  489. IDS_ERROR_SDO_ERROR_GET_CONDTEXT,
  490. NULL,
  491. hr
  492. );
  493. return FALSE;
  494. }
  495. _ASSERTE( V_VT(&varCondProp) == VT_BSTR);
  496. strExternCondText = V_BSTR(&varCondProp);
  497. DebugTrace(DEBUG_NAPMMC_POLICYPAGE1, "ConditionText: %ws",strExternCondText);
  498. // we are done with this condition sdo
  499. spConditionSdo.Release();
  500. varCondProp.Clear();
  501. // now we need to strip off the unnecessary prefix string in
  502. // the condition text
  503. hr = StripCondTextPrefix(
  504. strExternCondText,
  505. strCondText,
  506. strCondAttr,
  507. &CondType
  508. );
  509. if ( FAILED(hr) )
  510. {
  511. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1,"StripCondTextPrefix() failed, err = %x", hr);
  512. ShowErrorDialog(m_hWnd,
  513. IDS_ERROR_INVALID_COND_SYNTAX,
  514. m_pPolicyNode->m_bstrDisplayName
  515. );
  516. // go to the next condition
  517. varCond.Clear();
  518. hr = spEnumVariant->Next( 1, &varCond, &ulCountReceived );
  519. continue;
  520. }
  521. DebugTrace(DEBUG_NAPMMC_POLICYPAGE1,
  522. "ConditionText: %ws, CondAttr: %ws, CondType: %d",
  523. strCondText,
  524. strCondAttr,
  525. (int)CondType
  526. );
  527. switch(CondType)
  528. {
  529. case IAS_TIMEOFDAY_CONDITION: AttrId = IAS_ATTRIBUTE_NP_TIME_OF_DAY; break;
  530. case IAS_NTGROUPS_CONDITION: AttrId = IAS_ATTRIBUTE_NTGROUPS; break;
  531. case IAS_MATCH_CONDITION: {
  532. BSTR bstrName = SysAllocString(strCondAttr);
  533. if ( bstrName == NULL )
  534. {
  535. ShowErrorDialog(m_hWnd,
  536. IDS_ERROR_CANT_CREATE_CONDATTR,
  537. (LPTSTR)(LPCTSTR)strCondAttr,
  538. hr
  539. );
  540. return FALSE;
  541. }
  542. hr = m_spDictionarySdo->GetAttributeID(bstrName, &AttrId);
  543. if ( FAILED(hr) )
  544. {
  545. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "GetAttributeID() failed, err = %x", hr);
  546. ShowErrorDialog(m_hWnd,
  547. IDS_ERROR_SDO_ERROR_GETATTROD,
  548. bstrName,
  549. hr
  550. );
  551. SysFreeString(bstrName);
  552. return FALSE;
  553. }
  554. SysFreeString(bstrName);
  555. }
  556. break;
  557. }
  558. // GetAt can throw exceptions.
  559. try
  560. {
  561. //
  562. // find the condition attribute ID in the attribute list
  563. //
  564. int nAttrIndex = m_pIASAttrList->Find(AttrId);
  565. if (nAttrIndex == -1)
  566. {
  567. //
  568. // the attribute is not even found in the attribute list
  569. //
  570. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, " Can't find this condattr in the list");
  571. ShowErrorDialog(m_hWnd, IDS_ERROR_CANT_FIND_ATTR);
  572. return FALSE;
  573. }
  574. switch( AttrId )
  575. {
  576. case IAS_ATTRIBUTE_NP_TIME_OF_DAY:
  577. // time of day condition
  578. pCondition = (CCondition*) new CTodCondition(m_pIASAttrList->GetAt(nAttrIndex),
  579. strCondText
  580. );
  581. break;
  582. case IAS_ATTRIBUTE_NTGROUPS:
  583. // nt group condition
  584. pCondition = (CCondition*) new CNTGroupsCondition(m_pIASAttrList->GetAt(nAttrIndex),
  585. strCondText,
  586. m_hWnd,
  587. m_pPolicyNode->m_pszServerAddress
  588. );
  589. break;
  590. default:
  591. {
  592. CComPtr<IIASAttributeInfo> spAttributeInfo = m_pIASAttrList->GetAt(nAttrIndex);
  593. _ASSERTE(spAttributeInfo);
  594. ATTRIBUTESYNTAX as;
  595. hr = spAttributeInfo->get_AttributeSyntax( &as );
  596. _ASSERTE( SUCCEEDED(hr) );
  597. if( as == IAS_SYNTAX_ENUMERATOR )
  598. {
  599. // enum-type condition
  600. CEnumCondition *pEnumCondition = new CEnumCondition(m_pIASAttrList->GetAt(nAttrIndex),
  601. strCondText
  602. );
  603. pCondition = pEnumCondition;
  604. }
  605. else
  606. {
  607. // match condition
  608. pCondition = (CCondition*) new CMatchCondition(m_pIASAttrList->GetAt(nAttrIndex),
  609. strCondText
  610. );
  611. }
  612. }
  613. break;
  614. } // switch
  615. // Add the newly created node to the list of Policys.
  616. m_ConditionList.Add(pCondition);
  617. // get the next condition
  618. varCond.Clear();
  619. hr = spEnumVariant->Next( 1, &varCond, &ulCountReceived );
  620. }
  621. catch(...)
  622. {
  623. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "Exception thrown while populating condition list");
  624. continue;
  625. }
  626. } // while
  627. } // if
  628. }
  629. return TRUE;
  630. }
  631. HRESULT ConditionList::PopulateConditions()
  632. {
  633. SendDlgItemMessage( IDC_LIST_POLICYPAGE1_CONDITIONS,
  634. LB_RESETCONTENT,
  635. 0,
  636. 0L
  637. );
  638. ATL::CString strDispCondText;
  639. for (int iIndex=0; iIndex<m_ConditionList.GetSize(); iIndex++)
  640. {
  641. strDispCondText = m_ConditionList[iIndex]->GetDisplayText();
  642. if ( iIndex != m_ConditionList.GetSize()-1 )
  643. {
  644. // it's not the last condition, then we put an 'AND' at the
  645. // end of the condition text
  646. strDispCondText += " AND";
  647. }
  648. // display it
  649. SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS,
  650. LB_ADDSTRING,
  651. 0,
  652. (LPARAM)(LPCTSTR)strDispCondText);
  653. }
  654. if ( m_ConditionList.GetSize() == 0)
  655. {
  656. // no condition, then disable "Remove" and "Edit"
  657. ::EnableWindow(GetDlgItem(IDC_BUTTON_CONDITION_REMOVE), FALSE);
  658. ::EnableWindow(GetDlgItem(IDC_BUTTON_CONDITION_EDIT), FALSE);
  659. }
  660. else
  661. {
  662. SendDlgItemMessage(IDC_LIST_POLICYPAGE1_CONDITIONS, LB_SETCURSEL, 0, 0L);
  663. ::EnableWindow(GetDlgItem(IDC_BUTTON_CONDITION_EDIT), TRUE);
  664. ::EnableWindow(GetDlgItem(IDC_BUTTON_CONDITION_REMOVE), TRUE);
  665. }
  666. AdjustHoritontalScroll();
  667. return S_OK;
  668. }
  669. HRESULT StripCondTextPrefix(
  670. ATL::CString& strExternCondText,
  671. ATL::CString& strCondText,
  672. ATL::CString& strCondAttr,
  673. CONDITIONTYPE* pCondType
  674. )
  675. {
  676. HRESULT hr = S_OK;
  677. // is it an empty string
  678. if ( strExternCondText.GetLength() == 0 )
  679. {
  680. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1,"Can't parse prefix: empty condition text");
  681. return E_INVALIDARG;
  682. }
  683. // a temporary copy
  684. ATL::CString strTempStr = (LPCTSTR)strExternCondText;
  685. WCHAR *pwzCondText = (WCHAR*)(LPCTSTR)strTempStr;
  686. strCondAttr = _T("");
  687. strCondText = _T("");
  688. // condition text will look like : AttributeMatch("attr=<reg>")
  689. // strip off the "AttributeMatch(" prefix
  690. WCHAR *pwzBeginCond = wcschr(pwzCondText, _T('('));
  691. WCHAR *pwzEndCond = wcsrchr(pwzCondText, _T(')'));
  692. if ( ( pwzBeginCond == NULL ) || ( pwzEndCond == NULL ) )
  693. {
  694. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1,"Can't parse prefix: no ( or ) found");
  695. return E_INVALIDARG;
  696. }
  697. //
  698. // now we should decide what kind of condition this is:
  699. //
  700. *pwzBeginCond = _T('\0');
  701. DebugTrace(DEBUG_NAPMMC_POLICYPAGE1, "ConditionType: %ws", pwzCondText);
  702. if ( _wcsicmp(pwzCondText, TOD_PREFIX) == 0 )
  703. {
  704. *pCondType = IAS_TIMEOFDAY_CONDITION;
  705. }
  706. else if ( _wcsicmp(pwzCondText, NTG_PREFIX) == 0 )
  707. {
  708. *pCondType = IAS_NTGROUPS_CONDITION;
  709. }
  710. else if ( _wcsicmp(pwzCondText, MATCH_PREFIX ) == 0 )
  711. {
  712. *pCondType = IAS_MATCH_CONDITION;
  713. }
  714. else
  715. {
  716. return E_INVALIDARG;
  717. }
  718. // skip the '(' sign
  719. pwzBeginCond += 2 ;
  720. // skip the ')' sign
  721. *(pwzEndCond-1) = _T('\0');
  722. // So right now the string between pwzBeginCond and pwzEndCond is the
  723. // real condition text
  724. strCondText = pwzBeginCond;
  725. if ( IAS_MATCH_CONDITION == *pCondType )
  726. {
  727. // for match-type condition, we need to get the condition attribute name
  728. WCHAR *pwzEqualSign = wcschr(pwzBeginCond, _T('='));
  729. if ( pwzEqualSign == NULL )
  730. {
  731. ErrorTrace(ERROR_NAPMMC_POLICYPAGE1, "Can't parse : there's no = found");
  732. return E_INVALIDARG;
  733. }
  734. *pwzEqualSign = _T('\0');
  735. strCondAttr = pwzBeginCond;
  736. }
  737. else
  738. {
  739. strCondAttr = _T("");
  740. }
  741. DebugTrace(DEBUG_NAPMMC_POLICYPAGE1, "Condition Attr: %ws", strCondAttr);
  742. return S_OK;
  743. }
  744. //////////////////////////////////////////////////////////////////////////////
  745. /*++
  746. WriteConditionListToSDO
  747. --*/
  748. //////////////////////////////////////////////////////////////////////////////
  749. HRESULT WriteConditionListToSDO( CSimpleArray<CCondition*> & ConditionList
  750. , ISdoCollection * pConditionCollectionSdo
  751. , HWND hWnd
  752. )
  753. {
  754. TRACE_FUNCTION("WriteConditionListToSDO()");
  755. HRESULT hr = S_OK;
  756. CComVariant var;
  757. // remove all the condition SDOs from the policy's sdo collection,
  758. // re-add everything if any condition has been changed
  759. DebugTrace(DEBUG_NAPMMC_POLICYPAGE1, "Regenerate all the conditions");
  760. hr = pConditionCollectionSdo->RemoveAll();
  761. if( FAILED( hr ) )
  762. {
  763. // We could not create the object.
  764. ErrorTrace(DEBUG_NAPMMC_POLICYPAGE1, "Couldn't clear conditions for this policy, err = %x", hr);
  765. ShowErrorDialog(hWnd,IDS_ERROR_SDO_ERROR_ADDCOND,NULL,hr);
  766. return hr;
  767. }
  768. // Hack for semi-randomly generated Condition names.
  769. static dwConditionName = 0;
  770. // add all conditions in the condition collection sdo
  771. for (int iIndex=0; iIndex< ConditionList.GetSize(); iIndex++)
  772. {
  773. // Add a condition object in the policy's condition collection
  774. CComPtr<IDispatch> spDispatch;
  775. // we have to set the pointer to NULL in order for the collection Sdo
  776. // to create a brand new one for us
  777. spDispatch.p = NULL;
  778. // We need random temp names for conditions we add.
  779. CComBSTR bstrName;
  780. TCHAR tzTempName[MAX_PATH+1];
  781. do
  782. {
  783. // Create a temporary name. We used a random number
  784. // so the chance of getting identical names is very small.
  785. wsprintf(tzTempName, _T("Condition%lu"), dwConditionName++ );
  786. ATLTRACE(L"tzTempName: %ls\n", tzTempName );
  787. bstrName.Empty();
  788. bstrName = tzTempName; // temporary policy name
  789. ATLTRACE(L"conditionSdoCollection->Add(%ls)\n", bstrName );
  790. hr = pConditionCollectionSdo->Add(bstrName, (IDispatch **) &spDispatch.p);
  791. //
  792. // we keep looping around until the policy can be successfully added.
  793. // We will get E_INVALIDARG when the name already exists
  794. //
  795. } while ( hr == E_INVALIDARG );
  796. if( FAILED( hr ) )
  797. {
  798. // We could not create the object.
  799. ErrorTrace(DEBUG_NAPMMC_POLICYPAGE1, "Couldn't add condition for this policy, err = %x", hr);
  800. ShowErrorDialog(hWnd,IDS_ERROR_SDO_ERROR_ADDCOND,NULL,hr);
  801. return hr;
  802. }
  803. DebugTrace(DEBUG_NAPMMC_POLICYPAGE1, "conditionCollection->Add() succeeded");
  804. CComPtr<ISdo> spConditionSdo;
  805. // Query the returned IDispatch interface for an ISdo interface.
  806. _ASSERTE( spDispatch.p != NULL );
  807. hr = spDispatch.p->QueryInterface( IID_ISdo, (void **) &spConditionSdo );
  808. if( spConditionSdo == NULL )
  809. {
  810. ErrorTrace(DEBUG_NAPMMC_POLICYPAGE1, "QueryInterface for this a condition failed, err = %x", hr);
  811. ShowErrorDialog( hWnd
  812. , IDS_ERROR_SDO_ERROR_QUERYINTERFACE
  813. , NULL
  814. , hr
  815. );
  816. return hr;
  817. }
  818. // set condition text
  819. var.Clear();
  820. WCHAR *pwzCondText = ConditionList[iIndex]->GetConditionText();
  821. DebugTrace(DEBUG_NAPMMC_POLICYPAGE1,"ConditionText: %ws", pwzCondText);
  822. V_VT(&var)=VT_BSTR;
  823. V_BSTR(&var) = SysAllocString(pwzCondText);
  824. delete[] pwzCondText;
  825. hr = spConditionSdo->PutProperty(PROPERTY_CONDITION_TEXT, &var);
  826. if( FAILED (hr) )
  827. {
  828. ErrorTrace(DEBUG_NAPMMC_POLICYPAGE1, "Couldn't save this condition, err = %x", hr);
  829. ShowErrorDialog( hWnd
  830. , IDS_ERROR_SDO_ERROR_PUTPROP_CONDTEXT
  831. , NULL
  832. , hr
  833. );
  834. return hr;
  835. }
  836. var.Clear();
  837. } // for
  838. return hr;
  839. }