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.

747 lines
23 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: editorui.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "pch.h"
  11. #include <SnapBase.h>
  12. #include "resource.h"
  13. #include "attredit.h"
  14. #include "adsiedit.h"
  15. #include "editor.h"
  16. #include "editorui.h"
  17. #include "snapdata.h"
  18. #include "common.h"
  19. #include <aclpage.h>
  20. #include <dssec.h> // For AclEditor flags
  21. #include "connection.h"
  22. #ifdef DEBUG_ALLOCATOR
  23. #ifdef _DEBUG
  24. #define new DEBUG_NEW
  25. #undef THIS_FILE
  26. static char THIS_FILE[] = __FILE__;
  27. #endif
  28. #endif
  29. ////////////////////////////////////////////////////////////////////////////
  30. // this is used to fill in the attributes for RootDSE
  31. //
  32. typedef struct tagRootDSEAttr
  33. {
  34. LPCWSTR lpszAttr;
  35. LPCWSTR lpszSyntax;
  36. BOOL bMulti;
  37. } SYNTAXMAP;
  38. SYNTAXMAP g_ldapRootDSESyntax[] =
  39. {
  40. _T("currentTime"), _T("2.5.5.11"), FALSE,
  41. _T("subschemaSubentry"), _T("2.5.5.1"), FALSE,
  42. _T("serverName"), _T("2.5.5.1"), FALSE,
  43. _T("namingContexts"), _T("2.5.5.1"), TRUE,
  44. _T("defaultNamingContext"), _T("2.5.5.1"), FALSE,
  45. _T("schemaNamingContext"), _T("2.5.5.1"), FALSE,
  46. _T("configurationNamingContext"), _T("2.5.5.1"), FALSE,
  47. _T("rootDomainNamingContext"), _T("2.5.5.1"), FALSE,
  48. _T("supportedControl"), _T("2.5.5.2"), TRUE,
  49. _T("supportedLDAPVersion"), _T("2.5.5.9"), TRUE,
  50. _T("supportedLDAPPolicies"), _T("2.5.5.4"), TRUE,
  51. _T("supportedSASLMechanisms"), _T("2.5.5.4"), TRUE,
  52. _T("dsServiceName"), _T("2.5.5.1"), FALSE,
  53. _T("dnsHostName"), _T("2.5.5.4"), FALSE,
  54. _T("supportedCapabilities"), _T("2.5.5.2"), TRUE,
  55. _T("ldapServiceName"), _T("2.5.5.4"), FALSE,
  56. _T("highestCommittedUsn"), _T("2.5.5.4"), FALSE, // this should be an integer but after investigation I found it was a string
  57. _T("domainControllerFunctionality"),_T("2.5.5.9"), FALSE,
  58. _T("domainFunctionality"), _T("2.5.5.9"), FALSE,
  59. _T("forestFunctionality"), _T("2.5.5.9"), FALSE,
  60. _T("isGlobalCatalogReady"), _T("2.5.5.8"), FALSE,
  61. _T("isSynchronized"), _T("2.5.5.8"), FALSE,
  62. NULL, 0,
  63. };
  64. extern LPCWSTR g_lpszGC;
  65. /////////////////////////////////////////////////////////////////////////
  66. BEGIN_MESSAGE_MAP(CADSIEditPropertyPage, CPropertyPageBase)
  67. //{{AFX_MSG_MAP(CADsObjectDialog)
  68. ON_CBN_SELCHANGE(IDC_PROP_BOX, OnSelChangeAttrList)
  69. ON_CBN_SELCHANGE(IDC_PROPTYPES_BOX, OnSelChangePropList)
  70. //}}AFX_MSG_MAP
  71. END_MESSAGE_MAP()
  72. CADSIEditPropertyPage::CADSIEditPropertyPage()
  73. : CPropertyPageBase(IDD_PROPERTY_PAGE)
  74. {
  75. m_bExisting = TRUE;
  76. }
  77. CADSIEditPropertyPage::CADSIEditPropertyPage(CAttrList* pAttrs)
  78. : CPropertyPageBase(IDD_PROPERTY_PAGE)
  79. {
  80. ASSERT(pAttrs != NULL);
  81. m_pOldAttrList = pAttrs;
  82. m_bExisting = FALSE;
  83. CopyAttrList(pAttrs);
  84. }
  85. void CADSIEditPropertyPage::CopyAttrList(CAttrList* pAttrList)
  86. {
  87. m_AttrList.RemoveAll();
  88. POSITION pos = pAttrList->GetHeadPosition();
  89. while (pos != NULL)
  90. {
  91. m_AttrList.AddHead(pAttrList->GetNext(pos));
  92. }
  93. }
  94. BOOL CADSIEditPropertyPage::OnInitDialog()
  95. {
  96. CPropertyPageBase::OnInitDialog();
  97. // Get the dialog items
  98. //
  99. CEdit* pPathBox = (CEdit*)GetDlgItem(IDC_PATH_BOX);
  100. CEdit* pClassBox = (CEdit*)GetDlgItem(IDC_CLASS_BOX);
  101. CComboBox* pPropSelectBox = (CComboBox*)GetDlgItem(IDC_PROPTYPES_BOX);
  102. CComboBox* pPropertyBox = (CComboBox*)GetDlgItem(IDC_PROP_BOX);
  103. CStatic* pPathLabel = (CStatic*)GetDlgItem(IDC_PATH_LABEL);
  104. CStatic* pClassLabel = (CStatic*)GetDlgItem(IDC_CLASS_LABEL);
  105. CStatic* pFilterLabel = (CStatic*)GetDlgItem(IDC_FILTER_LABEL);
  106. CStatic* pPropertyLabel = (CStatic*)GetDlgItem(IDC_PROPERTY_LABEL);
  107. CStatic* pSyntaxLabel = (CStatic*)GetDlgItem(IDC_SYNTAX_LABEL);
  108. CStatic* pEditLabel = (CStatic*)GetDlgItem(IDC_EDIT_LABEL);
  109. CStatic* pValueLabel = (CStatic*)GetDlgItem(IDC_VALUE_LABEL);
  110. CButton* pAttrGroup = (CButton*)GetDlgItem(IDC_ATTR_GROUP);
  111. CStatic* pNoInfoLabel = (CStatic*)GetDlgItem(IDC_NO_INFO);
  112. if (m_bExisting)
  113. {
  114. // This determines whether the node is complete with data or not. If not we won't enable
  115. // the UI
  116. //
  117. BOOL bComplete = TRUE;
  118. CADsObject* pADsObject = NULL;
  119. CTreeNode* pTreeNode = GetHolder()->GetTreeNode();
  120. CADSIEditContainerNode* pContNode = dynamic_cast<CADSIEditContainerNode*>(pTreeNode);
  121. if (pContNode == NULL)
  122. {
  123. CADSIEditLeafNode* pLeafNode = dynamic_cast<CADSIEditLeafNode*>(pTreeNode);
  124. ASSERT(pLeafNode != NULL);
  125. pADsObject = pLeafNode->GetADsObject();
  126. m_pConnectData = pADsObject->GetConnectionNode()->GetConnectionData();
  127. bComplete = pADsObject->IsComplete();
  128. }
  129. else
  130. {
  131. pADsObject = pContNode->GetADsObject();
  132. m_pConnectData = pADsObject->GetConnectionNode()->GetConnectionData();
  133. bComplete = pADsObject->IsComplete();
  134. }
  135. // Initialize the attribute editor
  136. //
  137. m_attrEditor.Initialize(this, pTreeNode, m_sServer,
  138. IDC_EDITVALUE_BOX, IDC_SYNTAX_BOX,
  139. IDC_VALUE_EDITBOX, IDC_VALUE_LISTBOX,
  140. IDC_ADD_BUTTON, IDC_REMOVE_BUTTON,
  141. bComplete);
  142. // Get the UI to reflect the data
  143. //
  144. if ( bComplete)
  145. {
  146. pPathBox->SetWindowText(m_sPath);
  147. GetProperties();
  148. pClassBox->SetWindowText(m_sClass);
  149. CString sMand, sOpt, sBoth;
  150. if (!sMand.LoadString(IDS_MANDATORY) ||
  151. !sOpt.LoadString(IDS_OPTIONAL) ||
  152. !sBoth.LoadString(IDS_BOTH))
  153. {
  154. ADSIEditMessageBox(IDS_MSG_FAIL_TO_LOAD, MB_OK);
  155. }
  156. if (m_pConnectData->IsRootDSE())
  157. {
  158. pPropSelectBox->AddString(sMand);
  159. pPropSelectBox->SetCurSel(0);
  160. }
  161. else
  162. {
  163. pPropSelectBox->AddString(sMand);
  164. pPropSelectBox->AddString(sOpt);
  165. pPropSelectBox->AddString(sBoth);
  166. pPropSelectBox->SetCurSel(1);
  167. }
  168. OnSelChangePropList();
  169. pPropertyBox->SetCurSel(0);
  170. }
  171. else
  172. {
  173. pClassBox->ShowWindow(SW_HIDE);
  174. pPropSelectBox->ShowWindow(SW_HIDE);
  175. pPropertyBox->ShowWindow(SW_HIDE);
  176. pPathLabel->ShowWindow(SW_HIDE);
  177. pClassLabel->ShowWindow(SW_HIDE);
  178. pFilterLabel->ShowWindow(SW_HIDE);
  179. pPropertyLabel->ShowWindow(SW_HIDE);
  180. pSyntaxLabel->ShowWindow(SW_HIDE);
  181. pEditLabel->ShowWindow(SW_HIDE);
  182. pValueLabel->ShowWindow(SW_HIDE);
  183. pAttrGroup->ShowWindow(SW_HIDE);
  184. pNoInfoLabel->ShowWindow(SW_SHOW);
  185. }
  186. }
  187. else
  188. {
  189. // Initialize the attribute editor
  190. //
  191. m_attrEditor.Initialize(this, m_pConnectData, m_sServer,
  192. IDC_EDITVALUE_BOX, IDC_SYNTAX_BOX,
  193. IDC_VALUE_EDITBOX, IDC_VALUE_LISTBOX,
  194. IDC_ADD_BUTTON, IDC_REMOVE_BUTTON,
  195. TRUE, &m_AttrList);
  196. pPathBox->SetWindowText(m_sPath);
  197. GetProperties();
  198. pClassBox->SetWindowText(m_sClass);
  199. CString sMand, sOpt, sBoth;
  200. if (!sMand.LoadString(IDS_MANDATORY) ||
  201. !sOpt.LoadString(IDS_OPTIONAL) ||
  202. !sBoth.LoadString(IDS_BOTH))
  203. {
  204. ADSIEditMessageBox(IDS_MSG_FAIL_TO_LOAD, MB_OK);
  205. }
  206. if (m_pConnectData->IsRootDSE())
  207. {
  208. pPropSelectBox->AddString(sMand);
  209. pPropSelectBox->SetCurSel(0);
  210. }
  211. else
  212. {
  213. pPropSelectBox->AddString(sMand);
  214. pPropSelectBox->AddString(sOpt);
  215. pPropSelectBox->AddString(sBoth);
  216. pPropSelectBox->SetCurSel(1);
  217. }
  218. OnSelChangePropList();
  219. pPropertyBox->SetCurSel(0);
  220. }
  221. return TRUE;
  222. }
  223. BOOL CADSIEditPropertyPage::OnApply()
  224. {
  225. if( m_attrEditor.OnApply())
  226. {
  227. if (!m_bExisting)
  228. {
  229. m_pOldAttrList->RemoveAll();
  230. while (!m_AttrList.IsEmpty())
  231. {
  232. m_pOldAttrList->AddTail(m_AttrList.RemoveTail());
  233. }
  234. }
  235. }
  236. else
  237. {
  238. return FALSE;
  239. }
  240. return TRUE;
  241. }
  242. void CADSIEditPropertyPage::OnCancel()
  243. {
  244. if (!m_bExisting)
  245. {
  246. while (!m_AttrList.IsEmpty())
  247. {
  248. CADSIAttr* pAttr = m_AttrList.RemoveTail();
  249. ASSERT(pAttr != NULL);
  250. CString szProp;
  251. pAttr->GetProperty(szProp);
  252. if (!m_pOldAttrList->HasProperty(szProp))
  253. {
  254. delete pAttr;
  255. }
  256. }
  257. }
  258. }
  259. void CADSIEditPropertyPage::SetAttrList(CAttrList* pAttrList)
  260. {
  261. ASSERT(pAttrList != NULL);
  262. m_pOldAttrList = pAttrList;
  263. }
  264. void CADSIEditPropertyPage::OnSelChangePropList()
  265. {
  266. // Filter the properties list
  267. //
  268. FillAttrList();
  269. OnSelChangeAttrList();
  270. }
  271. void CADSIEditPropertyPage::OnSelChangeAttrList()
  272. {
  273. CComboBox* pPropertyBox = (CComboBox*)GetDlgItem(IDC_PROP_BOX);
  274. int idx, iCount;
  275. CString s;
  276. HRESULT hr;
  277. idx = pPropertyBox->GetCurSel();
  278. // Make sure a property was selected
  279. //
  280. if ( idx == LB_ERR )
  281. {
  282. return;
  283. }
  284. pPropertyBox->GetLBText( idx, s );
  285. // Have the attribute editor display the values for the new property
  286. //
  287. m_attrEditor.SetAttribute(s, m_sPath);
  288. }
  289. BOOL CADSIEditPropertyPage::GetProperties()
  290. {
  291. CString schema;
  292. //Get the class object so that we can get the properties
  293. //
  294. if (!m_pConnectData->IsRootDSE()) // Not RootDSE
  295. {
  296. m_pConnectData->GetAbstractSchemaPath(schema);
  297. schema += m_sClass;
  298. // bind to object with authentication
  299. //
  300. CComPtr<IADsClass> pClass;
  301. HRESULT hr, hCredResult;
  302. hr = OpenObjectWithCredentials(
  303. m_pConnectData,
  304. m_pConnectData->GetCredentialObject()->UseCredentials(),
  305. schema,
  306. IID_IADsClass,
  307. (LPVOID*) &pClass,
  308. GetSafeHwnd(),
  309. hCredResult
  310. );
  311. if ( FAILED(hr) )
  312. {
  313. if (SUCCEEDED(hCredResult))
  314. {
  315. ADSIEditErrorMessage(hr);
  316. }
  317. return FALSE;
  318. }
  319. // Get the Mandatory Properties
  320. //
  321. VARIANT var;
  322. VariantInit(&var);
  323. hr = pClass->get_MandatoryProperties(&var);
  324. if ( FAILED(hr) )
  325. {
  326. ADSIEditErrorMessage(hr);
  327. return FALSE;
  328. }
  329. VariantToStringList( var, m_sMandatoryAttrList );
  330. VariantClear(&var);
  331. // Remove the nTSecurityDescriptor from the list because the aclEditor replaces it for ui purposes
  332. //
  333. m_sMandatoryAttrList.RemoveAt(m_sMandatoryAttrList.Find(_T("nTSecurityDescriptor")));
  334. // Get the Optional Properties
  335. //
  336. VariantInit(&var);
  337. hr = pClass->get_OptionalProperties(&var);
  338. if ( FAILED(hr) )
  339. {
  340. ADSIEditErrorMessage(hr);
  341. return FALSE;
  342. }
  343. VariantToStringList( var, m_sOptionalAttrList );
  344. VariantClear(&var);
  345. }
  346. else // RootDSE
  347. {
  348. int idx=0;
  349. // Add in the predefined attributes for the RootDSE
  350. //
  351. while( g_ldapRootDSESyntax[idx].lpszAttr )
  352. {
  353. m_sMandatoryAttrList.AddTail(g_ldapRootDSESyntax[idx].lpszAttr);
  354. idx++;
  355. }
  356. }
  357. return TRUE;
  358. }
  359. void CADSIEditPropertyPage::FillAttrList()
  360. {
  361. CComboBox* pPropSelectBox = (CComboBox*)GetDlgItem(IDC_PROPTYPES_BOX);
  362. CComboBox* pPropertyBox = (CComboBox*)GetDlgItem(IDC_PROP_BOX);
  363. POSITION pos;
  364. CString s;
  365. // Clean out the property box
  366. //
  367. int iCount = pPropertyBox->GetCount();
  368. while (iCount > 0)
  369. {
  370. pPropertyBox->DeleteString(0);
  371. iCount--;
  372. }
  373. // Get the filter to use
  374. //
  375. int idx = pPropSelectBox->GetCurSel();
  376. if ( idx == LB_ERR )
  377. {
  378. return;
  379. }
  380. // Fill in the property box using the filter
  381. //
  382. if (idx == IDS_BOTH - IDS_MANDATORY)
  383. {
  384. AddPropertiesToBox(TRUE, TRUE);
  385. }
  386. else if (idx == IDS_MANDATORY - IDS_MANDATORY)
  387. {
  388. AddPropertiesToBox(TRUE, FALSE);
  389. }
  390. else
  391. {
  392. AddPropertiesToBox(FALSE, TRUE);
  393. }
  394. pPropertyBox->SetCurSel(0);
  395. }
  396. void CADSIEditPropertyPage::AddPropertiesToBox(BOOL bMand, BOOL bOpt)
  397. {
  398. CComboBox* pPropertyBox = (CComboBox*)GetDlgItem(IDC_PROP_BOX);
  399. POSITION pos;
  400. if (bMand)
  401. {
  402. // Add Mandatory Properties
  403. //
  404. pos = m_sMandatoryAttrList.GetHeadPosition();
  405. while( pos != NULL )
  406. {
  407. CString s = m_sMandatoryAttrList.GetNext(pos);
  408. if ( !s.IsEmpty())
  409. {
  410. pPropertyBox->AddString( s );
  411. }
  412. }
  413. }
  414. if (bOpt)
  415. {
  416. // Add Optional Properties
  417. //
  418. pos = m_sOptionalAttrList.GetHeadPosition();
  419. while( pos != NULL )
  420. {
  421. CString s = m_sOptionalAttrList.GetNext(pos);
  422. if ( !s.IsEmpty())
  423. {
  424. pPropertyBox->AddString( s );
  425. }
  426. }
  427. }
  428. }
  429. ///////////////////////////////////////////////////////////////////////////////////////////////////
  430. CADSIEditPropertyPageHolder::CADSIEditPropertyPageHolder(CADSIEditContainerNode* pContainerNode,
  431. CTreeNode* pThisNode, CComponentDataObject* pComponentData,
  432. LPCWSTR lpszClass, LPCWSTR lpszServer, LPCWSTR lpszPath)
  433. : CPropertyPageHolderBase(pContainerNode, pThisNode, pComponentData)
  434. {
  435. ASSERT(pComponentData != NULL);
  436. ASSERT(pContainerNode != NULL);
  437. m_pContainer = pContainerNode;
  438. ASSERT(pContainerNode == GetContainerNode());
  439. ASSERT(pThisNode != NULL);
  440. m_pAclEditorPage = NULL;
  441. m_bAutoDeletePages = FALSE; // we have the page as embedded member
  442. m_sPath = lpszPath;
  443. m_pADs = NULL;
  444. //
  445. // This gets the CConnectionData from the ConnectionNode by finding a valid treenode and using its
  446. // CADsObject to get the ConnectionNode and then the CConnectionData
  447. //
  448. CADSIEditContainerNode* pNode = GetContainerNode();
  449. CADSIEditConnectionNode* pConnectNode = pNode->GetADsObject()->GetConnectionNode();
  450. CConnectionData* pConnectData = pConnectNode->GetConnectionData();
  451. CCredentialObject* pCredObject = pConnectData->GetCredentialObject();
  452. HRESULT hr, hCredResult;
  453. hr = OpenObjectWithCredentials(
  454. pConnectData,
  455. pConnectData->GetCredentialObject()->UseCredentials(),
  456. m_sPath,
  457. IID_IADs,
  458. (LPVOID*) &m_pADs,
  459. NULL,
  460. hCredResult
  461. );
  462. if (SUCCEEDED(hr))
  463. {
  464. //
  465. // Create the advanced attribute editor
  466. //
  467. hr = ::CoCreateInstance(CLSID_DsAttributeEditor, NULL, CLSCTX_INPROC_SERVER,
  468. IID_IDsAttributeEditor, (void**)&m_spIDsAttributeEditor);
  469. if (SUCCEEDED(hr))
  470. {
  471. CString szLDAP;
  472. pConnectData->GetLDAP(szLDAP);
  473. CString szServer;
  474. pConnectData->GetDomainServer(szServer);
  475. CString szPort;
  476. pConnectData->GetPort(szPort);
  477. // NTRAID#NTBUG9-762158-2003/01/12-artm
  478. // If targeting the GC the server name will be empty.
  479. CString szProviderServer;
  480. if (!szServer.IsEmpty())
  481. {
  482. if (!szPort.IsEmpty())
  483. {
  484. szProviderServer = szLDAP + szServer + _T(":") + szPort + _T("/");
  485. }
  486. else
  487. {
  488. szProviderServer = szLDAP + szServer + _T("/");
  489. }
  490. }
  491. else
  492. {
  493. szProviderServer = szLDAP;
  494. }
  495. DS_ATTREDITOR_BINDINGINFO attrInfo = {0};
  496. attrInfo.dwSize = sizeof(DS_ATTREDITOR_BINDINGINFO);
  497. attrInfo.lpfnBind = BindingCallbackFunction;
  498. attrInfo.lParam = (LPARAM)pCredObject;
  499. attrInfo.lpszProviderServer = const_cast<LPWSTR>((LPCWSTR)szProviderServer);
  500. if (pConnectData->IsRootDSE())
  501. {
  502. attrInfo.dwFlags = DSATTR_EDITOR_ROOTDSE;
  503. }
  504. if (pConnectData->IsGC())
  505. {
  506. attrInfo.dwFlags |= DSATTR_EDITOR_GC;
  507. }
  508. hr = m_spIDsAttributeEditor->Initialize(m_pADs, &attrInfo, this);
  509. }
  510. if (!pConnectData->IsRootDSE() && !pConnectData->IsGC())
  511. {
  512. if (pCredObject->UseCredentials())
  513. {
  514. CString szUsername;
  515. EncryptedString password;
  516. WCHAR* szPassword = NULL;
  517. pCredObject->GetUsername(szUsername);
  518. password = pCredObject->GetPassword();
  519. // Shouldn't happen, but let's check...
  520. ASSERT(password.GetLength() <= MAX_PASSWORD_LENGTH);
  521. szPassword = password.GetClearTextCopy();
  522. // If we ran out of memory just pass a NULL pwd instead
  523. // (not much else one can do w/in constructor).
  524. m_pAclEditorPage = CAclEditorPage::CreateInstanceEx(m_sPath,
  525. lpszServer,
  526. szUsername,
  527. szPassword,
  528. DSSI_NO_FILTER,
  529. this);
  530. // Clean up clear text copies (call even if we ran
  531. // out of memory and cleartext == NULL).
  532. password.DestroyClearTextCopy(szPassword);
  533. }
  534. else
  535. {
  536. m_pAclEditorPage = CAclEditorPage::CreateInstanceEx(m_sPath,
  537. NULL,
  538. NULL,
  539. NULL,
  540. DSSI_NO_FILTER,
  541. this);
  542. }
  543. }
  544. }
  545. else
  546. {
  547. if (!pConnectData->IsRootDSE() && !pConnectData->IsGC())
  548. {
  549. if (SUCCEEDED(hCredResult))
  550. {
  551. ADSIEditErrorMessage(hr);
  552. // Create the acl editor even if we were not successful binding, because
  553. // the object may be deny read and we would still want the acl editor
  554. if (pCredObject->UseCredentials())
  555. {
  556. CString szUsername;
  557. EncryptedString password;
  558. WCHAR* szPassword = NULL;
  559. pCredObject->GetUsername(szUsername);
  560. password = pCredObject->GetPassword();
  561. // Shouldn't happen, but let's check...
  562. ASSERT(password.GetLength() <= MAX_PASSWORD_LENGTH);
  563. szPassword = password.GetClearTextCopy();
  564. // If we ran out of memory just pass a NULL pwd instead
  565. // (not much else one can do w/in constructor).
  566. m_pAclEditorPage = CAclEditorPage::CreateInstanceEx(m_sPath,
  567. lpszServer,
  568. szUsername,
  569. szPassword,
  570. DSSI_NO_FILTER,
  571. this);
  572. // Clean up clear text copies (call even if we ran
  573. // out of memory and cleartext == NULL).
  574. password.DestroyClearTextCopy(szPassword);
  575. }
  576. else
  577. {
  578. m_pAclEditorPage = CAclEditorPage::CreateInstanceEx(m_sPath,
  579. NULL,
  580. NULL,
  581. NULL,
  582. DSSI_NO_FILTER,
  583. this);
  584. }
  585. return;
  586. }
  587. }
  588. }
  589. }
  590. HRESULT CADSIEditPropertyPageHolder::OnAddPage(int nPage, CPropertyPageBase* pPage)
  591. {
  592. HRESULT hr = S_OK;
  593. if (nPage == 0)
  594. {
  595. //
  596. // Add the advanced editor page
  597. //
  598. HPROPSHEETPAGE hAttrPage = NULL;
  599. if (m_spIDsAttributeEditor != NULL)
  600. {
  601. hr = m_spIDsAttributeEditor->GetPage(&hAttrPage);
  602. if (SUCCEEDED(hr))
  603. {
  604. hr = AddPageToSheetRaw(hAttrPage);
  605. }
  606. }
  607. }
  608. else if ( nPage == -1)
  609. {
  610. if (m_pAclEditorPage != NULL)
  611. {
  612. //
  613. // add the ACL editor page after the last, if present
  614. //
  615. HPROPSHEETPAGE hPage = m_pAclEditorPage->CreatePage();
  616. if (hPage == NULL)
  617. {
  618. return E_FAIL;
  619. }
  620. //
  621. // add the raw HPROPSHEETPAGE to sheet, not in the list
  622. //
  623. hr = AddPageToSheetRaw(hPage);
  624. }
  625. }
  626. return hr;
  627. }
  628. ///////////////////////////////////////////////////////////////////////////////////////////////
  629. ///////////////////////////////////////////////////////////////////////////////////////////////////
  630. CCreateWizPropertyPageHolder::CCreateWizPropertyPageHolder(CADSIEditContainerNode* pContainerNode,
  631. CComponentDataObject* pComponentData, LPCWSTR lpszClass, LPCWSTR lpszServer, CAttrList* pAttrList)
  632. : CPropertyPageHolderBase(pContainerNode, NULL, pComponentData), m_propPage(pAttrList)
  633. {
  634. ASSERT(pComponentData != NULL);
  635. ASSERT(pContainerNode != NULL);
  636. m_pContainer = pContainerNode;
  637. ASSERT(pContainerNode == GetContainerNode());
  638. m_bAutoDeletePages = FALSE; // we have the page as embedded member
  639. m_propPage.SetClass(lpszClass);
  640. m_propPage.SetServer(lpszServer);
  641. m_propPage.SetConnectionData(pContainerNode->GetADsObject()->GetConnectionNode()->GetConnectionData());
  642. AddPageToList((CPropertyPageBase*)&m_propPage);
  643. }