Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

796 lines
19 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: connection.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "pch.h"
  11. #include <SnapBase.h>
  12. #include "resource.h"
  13. #include "createwiz.h"
  14. #include "connection.h"
  15. #include "connectionui.h"
  16. #include "editorui.h"
  17. #include "filterui.h"
  18. #include "credui.h"
  19. #include "queryui.h"
  20. #ifdef DEBUG_ALLOCATOR
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. #endif
  27. ///////////////////////////////////////////////////////////////////////////////
  28. extern LPCWSTR g_lpszRootDSE;
  29. ///////////////////////////////////////////////////////////////////////////////
  30. // {5C225203-CFF7-11d2-8801-00C04F72ED31}
  31. const GUID CADSIEditConnectionNode::NodeTypeGUID =
  32. { 0x5c225203, 0xcff7, 0x11d2, { 0x88, 0x1, 0x0, 0xc0, 0x4f, 0x72, 0xed, 0x31 } };
  33. CADSIEditConnectionNode::~CADSIEditConnectionNode()
  34. {
  35. RemoveAndDeleteAllQueriesFromList();
  36. delete m_pConnectData;
  37. HRESULT hr = m_SchemaCache.Destroy();
  38. ASSERT(SUCCEEDED(hr));
  39. }
  40. bool CADSIEditConnectionNode::IsClassAContainer(CCredentialObject* pCredObject,
  41. PCWSTR pszClass,
  42. PCWSTR pszSchemaPath)
  43. {
  44. bool bContainer = false;
  45. do // false loop
  46. {
  47. if (!pCredObject ||
  48. !pszClass ||
  49. !pszSchemaPath)
  50. {
  51. ASSERT(pCredObject);
  52. ASSERT(pszClass);
  53. ASSERT(pszSchemaPath);
  54. bContainer = false;
  55. break;
  56. }
  57. CADSIEditClassCacheItemBase* pSchemaCacheItem = m_SchemaCache.FindClassCacheItem(pCredObject,
  58. pszClass,
  59. pszSchemaPath);
  60. if (pSchemaCacheItem)
  61. {
  62. bContainer = pSchemaCacheItem->IsContainer();
  63. }
  64. } while (false);
  65. return bContainer;
  66. }
  67. BOOL CADSIEditConnectionNode::OnEnumerate(CComponentDataObject* pComponentData, BOOL bAsync)
  68. {
  69. CString path, basePath;
  70. GetADsObject()->GetPath(path);
  71. m_pConnectData->GetBasePath(basePath);
  72. CComPtr<IDirectoryObject> spDirectoryObject;
  73. HRESULT hr, hCredResult;
  74. CADsObject* pObject = new CADsObject();
  75. if (pObject)
  76. {
  77. if (m_pConnectData->IsRootDSE())
  78. {
  79. pObject->SetContainer(TRUE);
  80. pObject->SetName(g_lpszRootDSE);
  81. pObject->SetPath(path);
  82. pObject->SetClass(g_lpszRootDSE);
  83. pObject->SetConnectionNode(this);
  84. pObject->SetIntermediateNode(TRUE);
  85. pObject->SetComplete(TRUE);
  86. CADSIEditContainerNode *pNewContNode = new CADSIEditContainerNode(pObject);
  87. if (pNewContNode)
  88. {
  89. pNewContNode->SetDisplayName(g_lpszRootDSE);
  90. VERIFY(AddChildToList(pNewContNode));
  91. }
  92. pComponentData->SetDescriptionBarText(this);
  93. }
  94. else
  95. {
  96. hr = OpenObjectWithCredentials(
  97. m_pConnectData,
  98. m_pConnectData->GetCredentialObject()->UseCredentials(),
  99. (LPWSTR)(LPCWSTR)path,
  100. IID_IDirectoryObject,
  101. (LPVOID*) &spDirectoryObject,
  102. NULL,
  103. hCredResult
  104. );
  105. if ( FAILED(hr) )
  106. {
  107. if (SUCCEEDED(hCredResult))
  108. {
  109. ADSIEditErrorMessage(hr);
  110. }
  111. if (pObject)
  112. {
  113. delete pObject;
  114. pObject = 0;
  115. }
  116. return FALSE;
  117. }
  118. ADS_OBJECT_INFO* pInfo = 0;
  119. hr = spDirectoryObject->GetObjectInformation(&pInfo);
  120. if (FAILED(hr))
  121. {
  122. ADSIEditErrorMessage(hr);
  123. if (pObject)
  124. {
  125. delete pObject;
  126. pObject = 0;
  127. }
  128. return FALSE;
  129. }
  130. // Name
  131. pObject->SetName(basePath);
  132. pObject->SetDN(basePath);
  133. pObject->SetPath(path);
  134. // Make sure the prefix is uppercase
  135. CString sBasePath(basePath);
  136. int idx = sBasePath.Find(L'=');
  137. if (idx != -1)
  138. {
  139. CString sPrefix, sRemaining;
  140. sPrefix = sBasePath.Left(idx);
  141. sPrefix.MakeUpper();
  142. int iCount = sBasePath.GetLength();
  143. sRemaining = sBasePath.Right(iCount - idx);
  144. sBasePath = sPrefix + sRemaining;
  145. }
  146. // Class
  147. pObject->SetClass(pInfo->pszClassName);
  148. pObject->SetIntermediateNode(TRUE);
  149. pObject->SetContainer(TRUE);
  150. pObject->SetComplete(TRUE);
  151. CADSIEditContainerNode *pNewContNode = new CADSIEditContainerNode(pObject);
  152. if (pNewContNode)
  153. {
  154. CString sName;
  155. pNewContNode->SetDisplayName(sBasePath);
  156. GetConnectionData()->SetIDirectoryInterface(spDirectoryObject);
  157. pNewContNode->GetADsObject()->SetConnectionNode(this);
  158. VERIFY(AddChildToList(pNewContNode));
  159. pComponentData->SetDescriptionBarText(this);
  160. FreeADsMem(pInfo);
  161. }
  162. }
  163. EnumerateQueries();
  164. }
  165. return TRUE;
  166. }
  167. void CADSIEditConnectionNode::EnumerateQueries()
  168. {
  169. POSITION pos = m_queryList.GetHeadPosition();
  170. while(pos != NULL)
  171. {
  172. CADSIEditQueryData* pQueryData = m_queryList.GetNext(pos);
  173. CADsObject* pObject = new CADsObject();
  174. if (pObject)
  175. {
  176. CString sPath, sName;
  177. pQueryData->GetName(sName);
  178. pObject->SetName(sName);
  179. pQueryData->GetRootPath(sPath);
  180. pObject->SetPath(sPath);
  181. pObject->SetComplete(TRUE);
  182. pObject->SetConnectionNode(this);
  183. pObject->SetContainer(TRUE);
  184. pObject->SetIntermediateNode(TRUE);
  185. CADSIEditQueryNode* pNewQuery = new CADSIEditQueryNode(pObject, pQueryData);
  186. if (pNewQuery)
  187. {
  188. CString sDisplayName;
  189. pQueryData->GetDisplayName(sDisplayName);
  190. pNewQuery->SetDisplayName(sDisplayName);
  191. VERIFY(AddChildToList(pNewQuery));
  192. }
  193. }
  194. }
  195. }
  196. BOOL CADSIEditConnectionNode::HasPropertyPages(DATA_OBJECT_TYPES type,
  197. BOOL* pbHideVerb,
  198. CNodeList* pNodeList)
  199. {
  200. *pbHideVerb = TRUE; // always hide the verb
  201. return FALSE;
  202. }
  203. BOOL CADSIEditConnectionNode::FindNode(LPCWSTR lpszPath, CList<CTreeNode*, CTreeNode*>& foundNodeList)
  204. {
  205. CString szPath;
  206. GetADsObject()->GetPath(szPath);
  207. if (wcscmp(lpszPath, (LPCWSTR)szPath) == 0)
  208. {
  209. foundNodeList.AddHead(this);
  210. return TRUE;
  211. }
  212. BOOL bFound = FALSE;
  213. POSITION pos;
  214. for (pos = m_containerChildList.GetHeadPosition(); pos != NULL; )
  215. {
  216. CTreeNode* pNode = m_containerChildList.GetNext(pos);
  217. CADSIEditContainerNode* pContNode = dynamic_cast<CADSIEditContainerNode*>(pNode);
  218. if (pContNode != NULL)
  219. {
  220. BOOL bTemp;
  221. bTemp = pContNode->FindNode(lpszPath, foundNodeList);
  222. if (!bFound)
  223. {
  224. bFound = bTemp;
  225. }
  226. }
  227. }
  228. return bFound;
  229. }
  230. int CADSIEditConnectionNode::GetImageIndex(BOOL bOpenImage)
  231. {
  232. int nIndex = 0;
  233. switch (m_nState)
  234. {
  235. case notLoaded:
  236. nIndex = SERVER_IMAGE_NOT_LOADED;
  237. break;
  238. case loading:
  239. nIndex = SERVER_IMAGE_LOADING;
  240. break;
  241. case loaded:
  242. nIndex = SERVER_IMAGE_LOADED;
  243. break;
  244. case unableToLoad:
  245. nIndex = SERVER_IMAGE_UNABLE_TO_LOAD;
  246. break;
  247. case accessDenied:
  248. nIndex = SERVER_IMAGE_ACCESS_DENIED;
  249. break;
  250. default:
  251. ASSERT(FALSE);
  252. }
  253. return nIndex;
  254. }
  255. void CADSIEditConnectionNode::OnChangeState(CComponentDataObject* pComponentDataObject)
  256. {
  257. switch (m_nState)
  258. {
  259. case notLoaded:
  260. case loaded:
  261. case unableToLoad:
  262. case accessDenied:
  263. {
  264. m_nState = loading;
  265. m_dwErr = 0;
  266. }
  267. break;
  268. case loading:
  269. {
  270. if (m_dwErr == 0)
  271. m_nState = loaded;
  272. else if (m_dwErr == ERROR_ACCESS_DENIED)
  273. m_nState = accessDenied;
  274. else
  275. m_nState = unableToLoad;
  276. }
  277. break;
  278. default:
  279. ASSERT(FALSE);
  280. }
  281. VERIFY(SUCCEEDED(pComponentDataObject->ChangeNode(this, CHANGE_RESULT_ITEM_ICON)));
  282. VERIFY(SUCCEEDED(pComponentDataObject->UpdateVerbState(this)));
  283. }
  284. BOOL CADSIEditConnectionNode::OnRefresh(CComponentDataObject* pComponentData,
  285. CNodeList* pNodeList)
  286. {
  287. BOOL bRet = FALSE;
  288. DWORD dwCount = 0;
  289. if (pNodeList == NULL)
  290. {
  291. dwCount = 1;
  292. }
  293. else
  294. {
  295. dwCount = pNodeList->GetCount();
  296. }
  297. if (dwCount > 1) // multiple selection
  298. {
  299. POSITION pos = pNodeList->GetHeadPosition();
  300. while (pos != NULL)
  301. {
  302. CTreeNode* pNode = pNodeList->GetNext(pos);
  303. ASSERT(pNode != NULL);
  304. CNodeList nodeList;
  305. nodeList.AddTail(pNode);
  306. if (!pNode->OnRefresh(pComponentData, &nodeList))
  307. {
  308. bRet = FALSE;
  309. }
  310. }
  311. }
  312. else if (dwCount == 1) // single selection
  313. {
  314. if(CContainerNode::OnRefresh(pComponentData, pNodeList))
  315. {
  316. CADSIEditContainerNode * pNextNode;
  317. POSITION pos = m_containerChildList.GetHeadPosition();
  318. while (pos != NULL)
  319. {
  320. pNextNode = dynamic_cast<CADSIEditContainerNode*>(m_containerChildList.GetNext(pos));
  321. ASSERT(pNextNode != NULL);
  322. CNodeList nodeList;
  323. nodeList.AddTail(pNextNode);
  324. pNextNode->OnRefresh(pComponentData, &nodeList);
  325. }
  326. return TRUE;
  327. }
  328. }
  329. return FALSE;
  330. }
  331. HRESULT CADSIEditConnectionNode::OnCommand(long nCommandID,
  332. DATA_OBJECT_TYPES type,
  333. CComponentDataObject* pComponentData,
  334. CNodeList* pNodeList)
  335. {
  336. ASSERT (pNodeList->GetCount() == 1); // should only be a single selection
  337. switch (nCommandID)
  338. {
  339. case IDM_SETTINGS_CONNECTION :
  340. OnSettings(pComponentData);
  341. break;
  342. case IDM_REMOVE_CONNECTION :
  343. OnRemove(pComponentData);
  344. break;
  345. case IDM_NEW_OBJECT :
  346. OnCreate(pComponentData);
  347. break;
  348. case IDM_FILTER :
  349. OnFilter(pComponentData);
  350. break;
  351. case IDM_UPDATE_SCHEMA :
  352. OnUpdateSchema();
  353. break;
  354. case IDM_NEW_QUERY :
  355. OnNewQuery(pComponentData);
  356. break;
  357. default:
  358. ASSERT(FALSE); // Unknown command!
  359. return E_FAIL;
  360. }
  361. return S_OK;
  362. }
  363. void CADSIEditConnectionNode::OnUpdateSchema()
  364. {
  365. // Force an update of the schema cache
  366. CString szRootDSE;
  367. CConnectionData* pConnectData = GetConnectionData();
  368. CComPtr<IADs> spDirObject;
  369. HRESULT hr = GetRootDSEObject(pConnectData, &spDirObject);
  370. if (FAILED(hr))
  371. {
  372. ADSIEditErrorMessage(hr);
  373. return;
  374. }
  375. VARIANT var;
  376. var.vt = VT_I4;
  377. var.lVal = 1;
  378. hr = spDirObject->Put(L"updateSchemaNow", var);
  379. if (FAILED(hr))
  380. {
  381. ADSIEditErrorMessage(hr);
  382. return;
  383. }
  384. CString szSchema;
  385. pConnectData->GetAbstractSchemaPath(szSchema);
  386. szSchema = szSchema.Left(szSchema.GetLength()- 1);
  387. CComPtr<IADs> spSchemaObject;
  388. HRESULT hCredResult;
  389. hr = OpenObjectWithCredentials(
  390. pConnectData,
  391. pConnectData->GetCredentialObject()->UseCredentials(),
  392. (LPWSTR)(LPCWSTR)szSchema,
  393. IID_IADs,
  394. (LPVOID*) &spSchemaObject,
  395. NULL,
  396. hCredResult
  397. );
  398. if ( FAILED(hr) )
  399. {
  400. if (SUCCEEDED(hCredResult))
  401. {
  402. ADSIEditErrorMessage(hr);
  403. }
  404. return;
  405. }
  406. hr = spSchemaObject->GetInfo();
  407. if (FAILED(hr))
  408. {
  409. ADSIEditErrorMessage(hr);
  410. }
  411. //
  412. // Now clear the schema cache
  413. //
  414. m_SchemaCache.Clear();
  415. ADSIEditMessageBox(IDS_SCHEMA_UPDATE_SUCCESSFUL, MB_OK);
  416. }
  417. void CADSIEditConnectionNode::OnNewQuery(CComponentDataObject* pComponentData)
  418. {
  419. CString sConnectPath;
  420. GetADsObject()->GetPath(sConnectPath);
  421. CCredentialObject* pCredObject = GetConnectionData()->GetCredentialObject();
  422. CADSIEditQueryDialog queryDialog(sConnectPath, pCredObject);
  423. if (queryDialog.DoModal() == IDOK)
  424. {
  425. BOOL bOneLevel;
  426. CString sQueryString, sName, sPath;
  427. queryDialog.GetResults(sName, sQueryString, sPath, &bOneLevel);
  428. CADSIEditConnectionNode* pConnectNode = GetADsObject()->GetConnectionNode();
  429. CADsObject* pObject = new CADsObject();
  430. if (pObject)
  431. {
  432. CADSIEditQueryData *pQueryData = new CADSIEditQueryData();
  433. if (pQueryData)
  434. {
  435. // Name
  436. pObject->SetName(sName);
  437. pQueryData->SetName(sName);
  438. // Set the root path of the query string
  439. pObject->SetPath(sPath);
  440. pQueryData->SetRootPath(sPath);
  441. // Set the query string
  442. pQueryData->SetFilter(sQueryString);
  443. pObject->SetIntermediateNode(TRUE);
  444. pObject->SetContainer(TRUE);
  445. pObject->SetComplete(TRUE);
  446. pObject->SetConnectionNode(pConnectNode);
  447. // Set the scope of the query
  448. ADS_SCOPEENUM scope;
  449. scope = (bOneLevel) ? ADS_SCOPE_ONELEVEL : ADS_SCOPE_SUBTREE;
  450. pQueryData->SetScope(scope);
  451. // Create the query node with imbedded objects
  452. CADSIEditQueryNode* pNewQueryNode = new CADSIEditQueryNode(pObject, pQueryData);
  453. if (pNewQueryNode)
  454. {
  455. //
  456. // Set the display name
  457. //
  458. CString sDisplayName;
  459. pQueryData->GetDisplayName(sDisplayName);
  460. pNewQueryNode->SetDisplayName(sDisplayName);
  461. //
  462. // Add to connection node's list of queries
  463. //
  464. pConnectNode->AddQueryToList(pQueryData);
  465. if (pConnectNode->IsExpanded())
  466. {
  467. VERIFY(pConnectNode->AddChildToListAndUI(pNewQueryNode, pComponentData));
  468. pComponentData->SetDescriptionBarText(this);
  469. }
  470. }
  471. }
  472. }
  473. }
  474. }
  475. void CADSIEditConnectionNode::OnFilter(CComponentDataObject* pComponentData)
  476. {
  477. CADSIFilterDialog filterDialog(m_pConnectData);
  478. if (filterDialog.DoModal() == IDOK)
  479. {
  480. CNodeList nodeList;
  481. nodeList.AddTail(this);
  482. OnRefresh(pComponentData, &nodeList);
  483. }
  484. }
  485. void CADSIEditConnectionNode::OnCreate(CComponentDataObject* pComponentData)
  486. {
  487. CCreatePageHolder* pHolder = new CCreatePageHolder(GetContainer(), this, pComponentData);
  488. ASSERT(pHolder != NULL);
  489. pHolder->SetSheetTitle(IDS_PROP_CONTAINER_TITLE, this);
  490. pHolder->DoModalWizard();
  491. }
  492. BOOL CADSIEditConnectionNode::OnSetDeleteVerbState(DATA_OBJECT_TYPES type,
  493. BOOL* pbHideVerb,
  494. CNodeList* pNodeList)
  495. {
  496. *pbHideVerb = TRUE; // always hid the verb
  497. return FALSE;
  498. }
  499. BOOL CADSIEditConnectionNode::OnAddMenuItem(LPCONTEXTMENUITEM2 pContextMenuItem,
  500. long *pInsertionAllowed)
  501. {
  502. if (IsThreadLocked() || IsSheetLocked())
  503. {
  504. pContextMenuItem->fFlags = MF_GRAYED;
  505. return TRUE;
  506. }
  507. if (GetConnectionData()->GetFilter()->InUse())
  508. {
  509. pContextMenuItem->fFlags = MF_CHECKED;
  510. return TRUE;
  511. }
  512. return TRUE;
  513. }
  514. void CADSIEditConnectionNode::OnRemove(CComponentDataObject* pComponentData)
  515. {
  516. CString sLoadString, sCaption;
  517. if (sLoadString.LoadString(IDS_MSG_REMOVE_CONNECTION))
  518. {
  519. sCaption.Format((LPWSTR)(LPCWSTR)sLoadString, GetDisplayName());
  520. }
  521. if (ADSIEditMessageBox(sCaption, MB_OKCANCEL) == IDOK)
  522. {
  523. if (IsSheetLocked())
  524. {
  525. if (!CanCloseSheets())
  526. return;
  527. pComponentData->GetPropertyPageHolderTable()->DeleteSheetsOfNode(this);
  528. }
  529. ASSERT(!IsSheetLocked());
  530. // now remove from the UI
  531. DeleteHelper(pComponentData);
  532. pComponentData->SetDescriptionBarText(GetContainer());
  533. pComponentData->UpdateResultPaneView(GetContainer());
  534. delete this; // gone
  535. }
  536. }
  537. void CADSIEditConnectionNode::OnSettings(CComponentDataObject* pComponentData)
  538. {
  539. CWaitCursor cursor;
  540. CComponentDataObject* pComponentDataObject =
  541. ((CRootData*)(GetContainer()->GetRootContainer()))->GetComponentDataObject();
  542. ASSERT(pComponentDataObject != NULL);
  543. CContainerNode* pContNode = dynamic_cast<CContainerNode*>(GetContainer());
  544. ASSERT(pContNode != NULL);
  545. CADSIEditConnectDialog ConnectDialog(pContNode,
  546. this,
  547. pComponentDataObject,
  548. m_pConnectData);
  549. if (ConnectDialog.DoModal() == IDOK)
  550. {
  551. cursor.Restore();
  552. if (HasQueries())
  553. {
  554. if (AfxMessageBox(IDS_MSG_EXISTING_QUERIES, MB_YESNO) == IDYES)
  555. {
  556. RemoveAllQueriesFromList();
  557. }
  558. }
  559. CNodeList nodeList;
  560. nodeList.AddTail(this);
  561. OnRefresh(pComponentData, &nodeList);
  562. }
  563. }
  564. BOOL CADSIEditConnectionNode::OnSetRefreshVerbState(DATA_OBJECT_TYPES type,
  565. BOOL* pbHide,
  566. CNodeList* pNodeList)
  567. {
  568. ASSERT(pNodeList->GetCount() == 1);
  569. *pbHide = FALSE;
  570. return !IsThreadLocked();
  571. }
  572. HRESULT CADSIEditConnectionNode::CreateFromStream(IStream* pStm, CADSIEditConnectionNode** ppConnectionNode)
  573. {
  574. WCHAR szBuffer[MAX_CONNECT_NAME_LENGTH + 1];
  575. ULONG nLen; // WCHAR counting NULL
  576. ULONG cbRead;
  577. VERIFY(SUCCEEDED(pStm->Read((void*)&nLen,sizeof(UINT), &cbRead)));
  578. ASSERT(cbRead == sizeof(UINT));
  579. VERIFY(SUCCEEDED(pStm->Read((void*)szBuffer,sizeof(WCHAR)*nLen, &cbRead)));
  580. ASSERT(cbRead == sizeof(WCHAR)*nLen);
  581. CConnectionData* pConnect = CConnectionData::Load(pStm);
  582. *ppConnectionNode = new CADSIEditConnectionNode(pConnect);
  583. ASSERT(*ppConnectionNode != NULL);
  584. CString szDisplayExtra, szDisplay;
  585. pConnect->GetDomainServer(szDisplayExtra);
  586. szDisplay = CString(szBuffer) + L" [" + szDisplayExtra + L"]";
  587. (*ppConnectionNode)->SetDisplayName(szDisplay);
  588. (*ppConnectionNode)->SetConnectionNode(*ppConnectionNode);
  589. (*ppConnectionNode)->LoadQueryListFromStream(pStm);
  590. return S_OK;
  591. }
  592. HRESULT CADSIEditConnectionNode::SaveToStream(IStream* pStm)
  593. {
  594. // for each connection name, write # of chars+NULL, and then the name
  595. ULONG cbWrite;
  596. CString szName;
  597. m_pConnectData->GetName(szName);
  598. SaveStringToStream(pStm, szName);
  599. m_pConnectData->Save(pStm);
  600. SaveQueryListToStream(pStm);
  601. return S_OK;
  602. }
  603. void CADSIEditConnectionNode::LoadQueryListFromStream(IStream* pStm)
  604. {
  605. ULONG cbRead;
  606. int iCount;
  607. VERIFY(SUCCEEDED(pStm->Read((void*)&iCount,sizeof(int), &cbRead)));
  608. ASSERT(cbRead == sizeof(int));
  609. for (int idx = 0; idx < iCount; idx++)
  610. {
  611. CADSIEditQueryData* pQueryData = new CADSIEditQueryData();
  612. CString sName, sQueryString, sPath;
  613. LoadStringFromStream(pStm, sName);
  614. LoadStringFromStream(pStm, sQueryString);
  615. LoadStringFromStream(pStm, sPath);
  616. pQueryData->SetName(sName);
  617. pQueryData->SetFilter(sQueryString);
  618. CString sRootPath;
  619. BuildQueryPath(sPath, sRootPath);
  620. pQueryData->SetRootPath(sRootPath);
  621. ADS_SCOPEENUM scope;
  622. VERIFY(SUCCEEDED(pStm->Read((void*)&scope, sizeof(ADS_SCOPEENUM), &cbRead)));
  623. ASSERT(cbRead == sizeof(ADS_SCOPEENUM));
  624. pQueryData->SetScope(scope);
  625. AddQueryToList(pQueryData);
  626. }
  627. }
  628. void CADSIEditConnectionNode::BuildQueryPath(const CString& sPath, CString& sRootPath)
  629. {
  630. CConnectionData* pConnectData = GetConnectionData();
  631. CString sServer, sLDAP, sPort, sTemp;
  632. pConnectData->GetDomainServer(sServer);
  633. pConnectData->GetLDAP(sLDAP);
  634. pConnectData->GetPort(sPort);
  635. if (sServer != _T(""))
  636. {
  637. sTemp = sLDAP + sServer;
  638. if (sPort != _T(""))
  639. {
  640. sTemp = sTemp + _T(":") + sPort + _T("/");
  641. }
  642. else
  643. {
  644. sTemp = sTemp + _T("/");
  645. }
  646. sRootPath = sTemp + sPath;
  647. }
  648. else
  649. {
  650. sRootPath = sLDAP + sPath;
  651. }
  652. }
  653. void CADSIEditConnectionNode::SaveQueryListToStream(IStream* pStm)
  654. {
  655. ULONG cbWrite;
  656. int iCount = m_queryList.GetCount();
  657. VERIFY(SUCCEEDED(pStm->Write((void*)&iCount, sizeof(int),&cbWrite)));
  658. ASSERT(cbWrite == sizeof(int));
  659. POSITION pos = m_queryList.GetHeadPosition();
  660. while (pos != NULL)
  661. {
  662. CADSIEditQueryData* pQueryData = m_queryList.GetNext(pos);
  663. ASSERT(pQueryData != NULL);
  664. ADS_SCOPEENUM scope;
  665. CString sName, sQueryString, sRootPath;
  666. pQueryData->GetName(sName);
  667. pQueryData->GetFilter(sQueryString);
  668. pQueryData->GetDisplayPath(sRootPath);
  669. scope = pQueryData->GetScope();
  670. // save the query info to stream
  671. SaveStringToStream(pStm, sName);
  672. SaveStringToStream(pStm, sQueryString);
  673. SaveStringToStream(pStm, sRootPath);
  674. // Save the scope
  675. VERIFY(SUCCEEDED(pStm->Write((void*)&scope, sizeof(ADS_SCOPEENUM),&cbWrite)));
  676. ASSERT(cbWrite == sizeof(ADS_SCOPEENUM));
  677. }
  678. }