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.

860 lines
24 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. 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. // NOTICE-NTRAID#NTBUG9-561513-2002/03/01-artm Validate lpszPath before using.
  206. if (!lpszPath)
  207. {
  208. // This should never happen.
  209. ASSERT(false);
  210. return FALSE;
  211. }
  212. CString szPath;
  213. GetADsObject()->GetPath(szPath);
  214. if (wcscmp(lpszPath, (LPCWSTR)szPath) == 0)
  215. {
  216. foundNodeList.AddHead(this);
  217. return TRUE;
  218. }
  219. BOOL bFound = FALSE;
  220. POSITION pos;
  221. for (pos = m_containerChildList.GetHeadPosition(); pos != NULL; )
  222. {
  223. CTreeNode* pNode = m_containerChildList.GetNext(pos);
  224. CADSIEditContainerNode* pContNode = dynamic_cast<CADSIEditContainerNode*>(pNode);
  225. if (pContNode != NULL)
  226. {
  227. BOOL bTemp;
  228. bTemp = pContNode->FindNode(lpszPath, foundNodeList);
  229. if (!bFound)
  230. {
  231. bFound = bTemp;
  232. }
  233. }
  234. }
  235. return bFound;
  236. }
  237. int CADSIEditConnectionNode::GetImageIndex(BOOL bOpenImage)
  238. {
  239. int nIndex = 0;
  240. switch (m_nState)
  241. {
  242. case notLoaded:
  243. nIndex = SERVER_IMAGE_NOT_LOADED;
  244. break;
  245. case loading:
  246. nIndex = SERVER_IMAGE_LOADING;
  247. break;
  248. case loaded:
  249. nIndex = SERVER_IMAGE_LOADED;
  250. break;
  251. case unableToLoad:
  252. nIndex = SERVER_IMAGE_UNABLE_TO_LOAD;
  253. break;
  254. case accessDenied:
  255. nIndex = SERVER_IMAGE_ACCESS_DENIED;
  256. break;
  257. default:
  258. ASSERT(FALSE);
  259. }
  260. return nIndex;
  261. }
  262. void CADSIEditConnectionNode::OnChangeState(CComponentDataObject* pComponentDataObject)
  263. {
  264. switch (m_nState)
  265. {
  266. case notLoaded:
  267. case loaded:
  268. case unableToLoad:
  269. case accessDenied:
  270. {
  271. m_nState = loading;
  272. m_dwErr = 0;
  273. }
  274. break;
  275. case loading:
  276. {
  277. if (m_dwErr == 0)
  278. m_nState = loaded;
  279. else if (m_dwErr == ERROR_ACCESS_DENIED)
  280. m_nState = accessDenied;
  281. else
  282. m_nState = unableToLoad;
  283. }
  284. break;
  285. default:
  286. ASSERT(FALSE);
  287. }
  288. VERIFY(SUCCEEDED(pComponentDataObject->ChangeNode(this, CHANGE_RESULT_ITEM_ICON)));
  289. VERIFY(SUCCEEDED(pComponentDataObject->UpdateVerbState(this)));
  290. }
  291. BOOL CADSIEditConnectionNode::OnRefresh(CComponentDataObject* pComponentData,
  292. CNodeList* pNodeList)
  293. {
  294. BOOL bRet = FALSE;
  295. DWORD dwCount = 0;
  296. if (pNodeList == NULL)
  297. {
  298. dwCount = 1;
  299. }
  300. else
  301. {
  302. dwCount = pNodeList->GetCount();
  303. }
  304. if (dwCount > 1) // multiple selection
  305. {
  306. POSITION pos = pNodeList->GetHeadPosition();
  307. while (pos != NULL)
  308. {
  309. CTreeNode* pNode = pNodeList->GetNext(pos);
  310. ASSERT(pNode != NULL);
  311. CNodeList nodeList;
  312. nodeList.AddTail(pNode);
  313. if (!pNode->OnRefresh(pComponentData, &nodeList))
  314. {
  315. bRet = FALSE;
  316. }
  317. }
  318. }
  319. else if (dwCount == 1) // single selection
  320. {
  321. if(CContainerNode::OnRefresh(pComponentData, pNodeList))
  322. {
  323. CADSIEditContainerNode * pNextNode;
  324. POSITION pos = m_containerChildList.GetHeadPosition();
  325. while (pos != NULL)
  326. {
  327. pNextNode = dynamic_cast<CADSIEditContainerNode*>(m_containerChildList.GetNext(pos));
  328. ASSERT(pNextNode != NULL);
  329. CNodeList nodeList;
  330. nodeList.AddTail(pNextNode);
  331. pNextNode->OnRefresh(pComponentData, &nodeList);
  332. }
  333. return TRUE;
  334. }
  335. }
  336. return FALSE;
  337. }
  338. HRESULT CADSIEditConnectionNode::OnCommand(long nCommandID,
  339. DATA_OBJECT_TYPES type,
  340. CComponentDataObject* pComponentData,
  341. CNodeList* pNodeList)
  342. {
  343. ASSERT (pNodeList->GetCount() == 1); // should only be a single selection
  344. switch (nCommandID)
  345. {
  346. case IDM_SETTINGS_CONNECTION :
  347. OnSettings(pComponentData);
  348. break;
  349. case IDM_REMOVE_CONNECTION :
  350. OnRemove(pComponentData);
  351. break;
  352. case IDM_NEW_OBJECT :
  353. OnCreate(pComponentData);
  354. break;
  355. case IDM_FILTER :
  356. OnFilter(pComponentData);
  357. break;
  358. case IDM_UPDATE_SCHEMA :
  359. OnUpdateSchema();
  360. break;
  361. case IDM_NEW_QUERY :
  362. OnNewQuery(pComponentData);
  363. break;
  364. default:
  365. ASSERT(FALSE); // Unknown command!
  366. return E_FAIL;
  367. }
  368. return S_OK;
  369. }
  370. void CADSIEditConnectionNode::OnUpdateSchema()
  371. {
  372. // Force an update of the schema cache
  373. CString szRootDSE;
  374. CConnectionData* pConnectData = GetConnectionData();
  375. CComPtr<IADs> spDirObject;
  376. HRESULT hr = GetRootDSEObject(pConnectData, &spDirObject);
  377. if (FAILED(hr))
  378. {
  379. ADSIEditErrorMessage(hr);
  380. return;
  381. }
  382. VARIANT var;
  383. var.vt = VT_I4;
  384. var.lVal = 1;
  385. hr = spDirObject->Put(CComBSTR(L"updateSchemaNow"), var);
  386. if (FAILED(hr))
  387. {
  388. ADSIEditErrorMessage(hr);
  389. return;
  390. }
  391. CString szSchema;
  392. pConnectData->GetAbstractSchemaPath(szSchema);
  393. szSchema = szSchema.Left(szSchema.GetLength()- 1);
  394. CComPtr<IADs> spSchemaObject;
  395. HRESULT hCredResult;
  396. hr = OpenObjectWithCredentials(
  397. pConnectData,
  398. pConnectData->GetCredentialObject()->UseCredentials(),
  399. szSchema,
  400. IID_IADs,
  401. (LPVOID*) &spSchemaObject,
  402. NULL,
  403. hCredResult
  404. );
  405. if ( FAILED(hr) )
  406. {
  407. if (SUCCEEDED(hCredResult))
  408. {
  409. ADSIEditErrorMessage(hr);
  410. }
  411. return;
  412. }
  413. hr = spSchemaObject->GetInfo();
  414. if (FAILED(hr))
  415. {
  416. ADSIEditErrorMessage(hr);
  417. }
  418. //
  419. // Now clear the schema cache
  420. //
  421. m_SchemaCache.Clear();
  422. ADSIEditMessageBox(IDS_SCHEMA_UPDATE_SUCCESSFUL, MB_OK);
  423. }
  424. void CADSIEditConnectionNode::OnNewQuery(CComponentDataObject* pComponentData)
  425. {
  426. CThemeContextActivator activator;
  427. CString sConnectPath;
  428. GetADsObject()->GetPath(sConnectPath);
  429. CConnectionData* pConnectData = GetConnectionData();
  430. CCredentialObject* pCredObject = pConnectData->GetCredentialObject();
  431. CString szServer;
  432. pConnectData->GetDomainServer(szServer);
  433. CADSIEditQueryDialog queryDialog(szServer, sConnectPath, pCredObject);
  434. if (queryDialog.DoModal() == IDOK)
  435. {
  436. BOOL bOneLevel;
  437. CString sQueryString, sName, sPath;
  438. queryDialog.GetResults(sName, sQueryString, sPath, &bOneLevel);
  439. CADSIEditConnectionNode* pConnectNode = GetADsObject()->GetConnectionNode();
  440. CADsObject* pObject = new CADsObject();
  441. if (pObject)
  442. {
  443. CADSIEditQueryData *pQueryData = new CADSIEditQueryData();
  444. if (pQueryData)
  445. {
  446. // Name
  447. pObject->SetName(sName);
  448. pQueryData->SetName(sName);
  449. // Set the root path of the query string
  450. pObject->SetPath(sPath);
  451. pQueryData->SetRootPath(sPath);
  452. // Set the query string
  453. pQueryData->SetFilter(sQueryString);
  454. pObject->SetIntermediateNode(TRUE);
  455. pObject->SetContainer(TRUE);
  456. pObject->SetComplete(TRUE);
  457. pObject->SetConnectionNode(pConnectNode);
  458. // Set the scope of the query
  459. ADS_SCOPEENUM scope;
  460. scope = (bOneLevel) ? ADS_SCOPE_ONELEVEL : ADS_SCOPE_SUBTREE;
  461. pQueryData->SetScope(scope);
  462. // Create the query node with imbedded objects
  463. CADSIEditQueryNode* pNewQueryNode = new CADSIEditQueryNode(pObject, pQueryData);
  464. if (pNewQueryNode)
  465. {
  466. //
  467. // Set the display name
  468. //
  469. CString sDisplayName;
  470. pQueryData->GetDisplayName(sDisplayName);
  471. pNewQueryNode->SetDisplayName(sDisplayName);
  472. //
  473. // Add to connection node's list of queries
  474. //
  475. pConnectNode->AddQueryToList(pQueryData);
  476. if (pConnectNode->IsExpanded())
  477. {
  478. VERIFY(pConnectNode->AddChildToListAndUI(pNewQueryNode, pComponentData));
  479. pComponentData->SetDescriptionBarText(this);
  480. }
  481. }
  482. else
  483. {
  484. delete pObject;
  485. pObject = 0;
  486. delete pQueryData;
  487. pQueryData = 0;
  488. }
  489. }
  490. else
  491. {
  492. delete pObject;
  493. pObject = 0;
  494. }
  495. }
  496. }
  497. }
  498. void CADSIEditConnectionNode::OnFilter(CComponentDataObject* pComponentData)
  499. {
  500. CThemeContextActivator activator;
  501. CADSIFilterDialog filterDialog(m_pConnectData);
  502. if (filterDialog.DoModal() == IDOK)
  503. {
  504. CNodeList nodeList;
  505. nodeList.AddTail(this);
  506. OnRefresh(pComponentData, &nodeList);
  507. }
  508. }
  509. void CADSIEditConnectionNode::OnCreate(CComponentDataObject* pComponentData)
  510. {
  511. CThemeContextActivator activator;
  512. CCreatePageHolder* pHolder = new CCreatePageHolder(GetContainer(), this, pComponentData);
  513. ASSERT(pHolder != NULL);
  514. pHolder->SetSheetTitle(IDS_PROP_CONTAINER_TITLE, this);
  515. pHolder->DoModalWizard();
  516. }
  517. BOOL CADSIEditConnectionNode::OnSetDeleteVerbState(DATA_OBJECT_TYPES type,
  518. BOOL* pbHideVerb,
  519. CNodeList* pNodeList)
  520. {
  521. *pbHideVerb = TRUE; // always hid the verb
  522. return FALSE;
  523. }
  524. BOOL CADSIEditConnectionNode::OnAddMenuItem(LPCONTEXTMENUITEM2 pContextMenuItem,
  525. long *pInsertionAllowed)
  526. {
  527. if (IsThreadLocked() || IsSheetLocked())
  528. {
  529. pContextMenuItem->fFlags = MF_GRAYED;
  530. return TRUE;
  531. }
  532. if (GetConnectionData()->GetFilter()->InUse())
  533. {
  534. pContextMenuItem->fFlags = MF_CHECKED;
  535. return TRUE;
  536. }
  537. return TRUE;
  538. }
  539. HRESULT CADSIEditConnectionNode::OnRename(CComponentDataObject* pComponentData,
  540. LPWSTR lpszNewName)
  541. {
  542. HRESULT hr = S_OK;
  543. BOOL bLocked = IsThreadLocked();
  544. ASSERT(!bLocked); // cannot do refresh on locked node, the UI should prevent this
  545. if (bLocked)
  546. {
  547. return hr;
  548. }
  549. if (!lpszNewName)
  550. {
  551. return E_INVALIDARG;
  552. }
  553. CString szDisplayExtra;
  554. m_pConnectData->GetDomainServer(szDisplayExtra);
  555. szDisplayExtra = L" [" + szDisplayExtra + L"]";
  556. m_pConnectData->SetName(lpszNewName);
  557. SetDisplayName(lpszNewName + szDisplayExtra);
  558. return hr;
  559. }
  560. void CADSIEditConnectionNode::OnRemove(CComponentDataObject* pComponentData)
  561. {
  562. CString sLoadString, sCaption;
  563. // NOTICE-2002/03/01-artm CString can throw out of memory exception,
  564. // but that needs to be handled at a higher level so don't worry about
  565. // it here.
  566. if (sLoadString.LoadString(IDS_MSG_REMOVE_CONNECTION))
  567. {
  568. sCaption.Format((LPWSTR)(LPCWSTR)sLoadString, GetDisplayName());
  569. }
  570. if (ADSIEditMessageBox(sCaption, MB_YESNO | MB_DEFBUTTON2) == IDYES)
  571. {
  572. if (IsSheetLocked())
  573. {
  574. if (!CanCloseSheets())
  575. return;
  576. pComponentData->GetPropertyPageHolderTable()->DeleteSheetsOfNode(this);
  577. }
  578. ASSERT(!IsSheetLocked());
  579. // now remove from the UI
  580. DeleteHelper(pComponentData);
  581. pComponentData->SetDescriptionBarText(GetContainer());
  582. pComponentData->UpdateResultPaneView(GetContainer());
  583. delete this; // gone
  584. }
  585. }
  586. void CADSIEditConnectionNode::OnSettings(CComponentDataObject* pComponentData)
  587. {
  588. CWaitCursor cursor;
  589. CThemeContextActivator activator;
  590. CComponentDataObject* pComponentDataObject =
  591. ((CRootData*)(GetContainer()->GetRootContainer()))->GetComponentDataObject();
  592. ASSERT(pComponentDataObject != NULL);
  593. CContainerNode* pContNode = dynamic_cast<CContainerNode*>(GetContainer());
  594. ASSERT(pContNode != NULL);
  595. CADSIEditConnectDialog ConnectDialog(pContNode,
  596. this,
  597. pComponentDataObject,
  598. m_pConnectData);
  599. if (ConnectDialog.DoModal() == IDOK)
  600. {
  601. cursor.Restore();
  602. if (HasQueries())
  603. {
  604. if (AfxMessageBox(IDS_MSG_EXISTING_QUERIES, MB_YESNO) == IDYES)
  605. {
  606. RemoveAllQueriesFromList();
  607. }
  608. }
  609. CNodeList nodeList;
  610. nodeList.AddTail(this);
  611. OnRefresh(pComponentData, &nodeList);
  612. }
  613. }
  614. BOOL CADSIEditConnectionNode::OnSetRefreshVerbState(DATA_OBJECT_TYPES type,
  615. BOOL* pbHide,
  616. CNodeList* pNodeList)
  617. {
  618. ASSERT(pNodeList->GetCount() == 1);
  619. *pbHide = FALSE;
  620. return !IsThreadLocked();
  621. }
  622. HRESULT CADSIEditConnectionNode::CreateFromStream(IStream* pStm, CADSIEditConnectionNode** ppConnectionNode)
  623. {
  624. WCHAR szBuffer[MAX_CONNECT_NAME_LENGTH + 1];
  625. ULONG nLen; // WCHAR counting NULL
  626. ULONG cbRead;
  627. VERIFY(SUCCEEDED(pStm->Read((void*)&nLen,sizeof(UINT), &cbRead)));
  628. ASSERT(cbRead == sizeof(UINT));
  629. VERIFY(SUCCEEDED(pStm->Read((void*)szBuffer,sizeof(WCHAR)*nLen, &cbRead)));
  630. ASSERT(cbRead == sizeof(WCHAR)*nLen);
  631. CConnectionData* pConnect = CConnectionData::Load(pStm);
  632. *ppConnectionNode = new CADSIEditConnectionNode(pConnect);
  633. ASSERT(*ppConnectionNode != NULL);
  634. CString szDisplayExtra, szDisplay;
  635. pConnect->GetDomainServer(szDisplayExtra);
  636. szDisplay = CString(szBuffer) + L" [" + szDisplayExtra + L"]";
  637. (*ppConnectionNode)->SetDisplayName(szDisplay);
  638. (*ppConnectionNode)->SetConnectionNode(*ppConnectionNode);
  639. (*ppConnectionNode)->LoadQueryListFromStream(pStm);
  640. return S_OK;
  641. }
  642. HRESULT CADSIEditConnectionNode::SaveToStream(IStream* pStm)
  643. {
  644. // for each connection name, write # of chars+NULL, and then the name
  645. ULONG cbWrite;
  646. CString szName;
  647. m_pConnectData->GetName(szName);
  648. SaveStringToStream(pStm, szName);
  649. m_pConnectData->Save(pStm);
  650. SaveQueryListToStream(pStm);
  651. return S_OK;
  652. }
  653. void CADSIEditConnectionNode::LoadQueryListFromStream(IStream* pStm)
  654. {
  655. ULONG cbRead;
  656. int iCount;
  657. VERIFY(SUCCEEDED(pStm->Read((void*)&iCount,sizeof(int), &cbRead)));
  658. ASSERT(cbRead == sizeof(int));
  659. for (int idx = 0; idx < iCount; idx++)
  660. {
  661. CADSIEditQueryData* pQueryData = new CADSIEditQueryData();
  662. CString sName, sQueryString, sPath;
  663. // FUTURE-2002/03/01-artm Function LoadStringFromStream() should return
  664. // success/error code and this function should call it.
  665. // Who knows what kind of stream we've been given and how it could
  666. // fail????
  667. LoadStringFromStream(pStm, sName);
  668. LoadStringFromStream(pStm, sQueryString);
  669. LoadStringFromStream(pStm, sPath);
  670. pQueryData->SetName(sName);
  671. pQueryData->SetFilter(sQueryString);
  672. CString sRootPath;
  673. BuildQueryPath(sPath, sRootPath);
  674. pQueryData->SetRootPath(sRootPath);
  675. ADS_SCOPEENUM scope;
  676. VERIFY(SUCCEEDED(pStm->Read((void*)&scope, sizeof(ADS_SCOPEENUM), &cbRead)));
  677. ASSERT(cbRead == sizeof(ADS_SCOPEENUM));
  678. pQueryData->SetScope(scope);
  679. AddQueryToList(pQueryData);
  680. }
  681. }
  682. void CADSIEditConnectionNode::BuildQueryPath(const CString& sPath, CString& sRootPath)
  683. {
  684. CConnectionData* pConnectData = GetConnectionData();
  685. CString sServer, sLDAP, sPort, sTemp;
  686. pConnectData->GetDomainServer(sServer);
  687. pConnectData->GetLDAP(sLDAP);
  688. pConnectData->GetPort(sPort);
  689. if (sServer != _T(""))
  690. {
  691. sTemp = sLDAP + sServer;
  692. if (sPort != _T(""))
  693. {
  694. sTemp = sTemp + _T(":") + sPort + _T("/");
  695. }
  696. else
  697. {
  698. sTemp = sTemp + _T("/");
  699. }
  700. sRootPath = sTemp + sPath;
  701. }
  702. else
  703. {
  704. sRootPath = sLDAP + sPath;
  705. }
  706. }
  707. void CADSIEditConnectionNode::SaveQueryListToStream(IStream* pStm)
  708. {
  709. ULONG cbWrite;
  710. int iCount = m_queryList.GetCount();
  711. VERIFY(SUCCEEDED(pStm->Write((void*)&iCount, sizeof(int),&cbWrite)));
  712. ASSERT(cbWrite == sizeof(int));
  713. POSITION pos = m_queryList.GetHeadPosition();
  714. while (pos != NULL)
  715. {
  716. CADSIEditQueryData* pQueryData = m_queryList.GetNext(pos);
  717. ASSERT(pQueryData != NULL);
  718. ADS_SCOPEENUM scope;
  719. CString sName, sQueryString, sRootPath;
  720. pQueryData->GetName(sName);
  721. pQueryData->GetFilter(sQueryString);
  722. pQueryData->GetDisplayPath(sRootPath);
  723. scope = pQueryData->GetScope();
  724. // save the query info to stream
  725. SaveStringToStream(pStm, sName);
  726. SaveStringToStream(pStm, sQueryString);
  727. SaveStringToStream(pStm, sRootPath);
  728. // Save the scope
  729. VERIFY(SUCCEEDED(pStm->Write((void*)&scope, sizeof(ADS_SCOPEENUM),&cbWrite)));
  730. ASSERT(cbWrite == sizeof(ADS_SCOPEENUM));
  731. }
  732. }