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.

3619 lines
98 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: server.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "preDNSsn.h"
  11. #include <SnapBase.h>
  12. #include "resource.h"
  13. #include "dnsutil.h"
  14. #include "DNSSnap.h"
  15. #include "snapdata.h"
  16. #include "server.h"
  17. #include "serverui.h"
  18. #include "servmon.h"
  19. #include "servwiz.h"
  20. #include "domain.h"
  21. #include "record.h"
  22. #include "zone.h"
  23. #include "ZoneWiz.h"
  24. #ifdef DEBUG_ALLOCATOR
  25. #ifdef _DEBUG
  26. #define new DEBUG_NEW
  27. #undef THIS_FILE
  28. static char THIS_FILE[] = __FILE__;
  29. #endif
  30. #endif
  31. ///////////////////////////////////////////////////////////////////////////////
  32. // GLOBAL FUNCTIONS
  33. LPCWSTR DNS_EVT_COMMAND_LINE = L"\\system32\\msdssevt.msc /computer=";
  34. LPCWSTR MMC_APP = L"\\system32\\mmc.exe";
  35. DNS_STATUS ServerHasCache(LPCWSTR lpszServerName, BOOL* pbRes)
  36. {
  37. USES_CONVERSION;
  38. *pbRes = FALSE;
  39. DWORD dwFilter = ZONE_REQUEST_CACHE;
  40. PDNS_RPC_ZONE_LIST pZoneList = NULL;
  41. DNS_STATUS err = ::DnssrvEnumZones(lpszServerName,
  42. dwFilter,
  43. NULL /*pszLastZone, unused for the moment */,
  44. &pZoneList);
  45. if (err == 0 &&
  46. pZoneList)
  47. {
  48. *pbRes = (pZoneList->dwZoneCount > 0);
  49. ::DnssrvFreeZoneList(pZoneList);
  50. }
  51. else
  52. {
  53. ASSERT(pZoneList);
  54. }
  55. return err;
  56. }
  57. DNS_STATUS ServerHasRootZone(LPCWSTR lpszServerName, BOOL* pbRes)
  58. {
  59. USES_CONVERSION;
  60. *pbRes = FALSE;
  61. DWORD dwFilter = ZONE_REQUEST_FORWARD | ZONE_REQUEST_PRIMARY | ZONE_REQUEST_SECONDARY;
  62. PDNS_RPC_ZONE_LIST pZoneList = NULL;
  63. DNS_STATUS err = ::DnssrvEnumZones(lpszServerName,
  64. dwFilter,
  65. NULL /*pszLastZone, unused for the moment */,
  66. &pZoneList);
  67. if (err == 0 && pZoneList)
  68. {
  69. for (DWORD iZone = 0; iZone < pZoneList->dwZoneCount; iZone++)
  70. {
  71. if (pZoneList->ZoneArray[iZone]->pszZoneName)
  72. {
  73. if (wcscmp(L".", pZoneList->ZoneArray[iZone]->pszZoneName) == 0)
  74. {
  75. *pbRes = TRUE;
  76. break;
  77. }
  78. }
  79. }
  80. }
  81. if (pZoneList != NULL)
  82. ::DnssrvFreeZoneList(pZoneList);
  83. return err;
  84. }
  85. ///////////////////////////////////////////////////////////////////////////////
  86. // CZoneInfoHolder : simple memory manager for arrays of zone info handles
  87. #define DEFAULT_ZONE_INFO_ARRAY_SIZE (128)
  88. #define MAX_ZONE_INFO_ARRAY_SIZE (0xffff)
  89. CZoneInfoHolder::CZoneInfoHolder()
  90. {
  91. AllocateMemory(DEFAULT_ZONE_INFO_ARRAY_SIZE);
  92. }
  93. CZoneInfoHolder::~CZoneInfoHolder()
  94. {
  95. FreeMemory();
  96. }
  97. void CZoneInfoHolder::AllocateMemory(DWORD dwArrSize)
  98. {
  99. TRACE(_T("CZoneInfoHolder::AllocateMemory(dwArrSize = %d)\n"), dwArrSize);
  100. m_dwArrSize = dwArrSize;
  101. DWORD dwMemSize = 2*m_dwArrSize*sizeof(PDNS_ZONE_INFO);
  102. m_zoneInfoArray = (PDNS_ZONE_INFO*)malloc(dwMemSize);
  103. if (m_zoneInfoArray != NULL)
  104. {
  105. ASSERT(m_zoneInfoArray != NULL);
  106. memset(m_zoneInfoArray, 0x0, dwMemSize);
  107. m_dwZoneCount = 0;
  108. #ifdef _DEBUG
  109. for (DWORD k=0; k< dwArrSize; k++)
  110. ASSERT(m_zoneInfoArray[k] == NULL);
  111. #endif
  112. }
  113. }
  114. void CZoneInfoHolder::FreeMemory()
  115. {
  116. if (m_zoneInfoArray != NULL)
  117. {
  118. TRACE(_T("CZoneInfoHolder::FreeMemory() m_dwArrSize = %d\n"), m_dwArrSize);
  119. ASSERT(m_dwArrSize > 0);
  120. //ASSERT(m_dwZoneCount <= m_dwArrSize);
  121. for (DWORD k=0; k < m_dwArrSize; k++)
  122. {
  123. if (m_zoneInfoArray[k] != NULL)
  124. {
  125. TRACE(_T("CZoneInfoHolder::FreeMemory() DnsFreeZoneInfo(m_zoneInfoArray[%d])\n"), k);
  126. ::DnssrvFreeZoneInfo(m_zoneInfoArray[k]);
  127. }
  128. }
  129. free(m_zoneInfoArray);
  130. m_zoneInfoArray = NULL;
  131. m_dwZoneCount = 0;
  132. m_dwArrSize = 0;
  133. }
  134. }
  135. BOOL CZoneInfoHolder::Grow()
  136. {
  137. TRACE(_T("CZoneInfoHolder::Grow()\n"));
  138. if (m_dwArrSize >= MAX_ZONE_INFO_ARRAY_SIZE)
  139. return FALSE;
  140. ASSERT(m_dwArrSize > 0);
  141. ASSERT(m_dwZoneCount > m_dwArrSize);
  142. DWORD dwNewSize = m_dwZoneCount;
  143. FreeMemory();
  144. AllocateMemory(dwNewSize);
  145. return TRUE;
  146. }
  147. /////////////////////////////////////////////////////////////////////////
  148. // CDNSMTContainerNode
  149. CDNSMTContainerNode::CDNSMTContainerNode()
  150. {
  151. m_pServerNode = NULL;
  152. m_nState = notLoaded;
  153. m_szDescriptionBar = _T("");
  154. m_pColumnSet = NULL;
  155. }
  156. HRESULT CDNSMTContainerNode::OnSetToolbarVerbState(IToolbar* pToolbar,
  157. CNodeList*)
  158. {
  159. HRESULT hr = S_OK;
  160. //
  161. // Set the button state for each button on the toolbar
  162. //
  163. hr = pToolbar->SetButtonState(toolbarNewServer, ENABLED, FALSE);
  164. hr = pToolbar->SetButtonState(toolbarNewZone, ENABLED, FALSE);
  165. hr = pToolbar->SetButtonState(toolbarNewRecord, ENABLED, FALSE);
  166. return hr;
  167. }
  168. LPWSTR CDNSMTContainerNode::GetDescriptionBarText()
  169. {
  170. static CString szFilterEnabled;
  171. if(((CDNSRootData*)GetRootContainer())->IsFilteringEnabled())
  172. {
  173. if (szFilterEnabled.IsEmpty())
  174. {
  175. szFilterEnabled.LoadString(IDS_FILTER_ENABLED);
  176. }
  177. m_szDescriptionBar = szFilterEnabled;
  178. }
  179. else
  180. {
  181. m_szDescriptionBar = _T("");
  182. }
  183. return (LPWSTR)(LPCWSTR)m_szDescriptionBar;
  184. }
  185. int CDNSMTContainerNode::GetImageIndex(BOOL)
  186. {
  187. int nIndex = 0;
  188. switch (m_nState)
  189. {
  190. case notLoaded:
  191. nIndex = FOLDER_IMAGE_NOT_LOADED;
  192. break;
  193. case loading:
  194. nIndex = FOLDER_IMAGE_LOADING;
  195. break;
  196. case loaded:
  197. nIndex = FOLDER_IMAGE_LOADED;
  198. break;
  199. case unableToLoad:
  200. nIndex = FOLDER_IMAGE_UNABLE_TO_LOAD;
  201. break;
  202. case accessDenied:
  203. nIndex = FOLDER_IMAGE_ACCESS_DENIED;
  204. break;
  205. default:
  206. ASSERT(FALSE);
  207. }
  208. return nIndex;
  209. }
  210. void CDNSMTContainerNode::OnChangeState(CComponentDataObject* pComponentDataObject)
  211. {
  212. switch (m_nState)
  213. {
  214. case notLoaded:
  215. case loaded:
  216. case unableToLoad:
  217. case accessDenied:
  218. {
  219. m_nState = loading;
  220. m_dwErr = 0;
  221. }
  222. break;
  223. case loading:
  224. {
  225. if (m_dwErr == 0)
  226. m_nState = loaded;
  227. else if (m_dwErr == ERROR_ACCESS_DENIED)
  228. m_nState = accessDenied;
  229. else
  230. m_nState = unableToLoad;
  231. }
  232. break;
  233. default:
  234. ASSERT(FALSE);
  235. }
  236. VERIFY(SUCCEEDED(pComponentDataObject->ChangeNode(this, CHANGE_RESULT_ITEM_ICON)));
  237. VERIFY(SUCCEEDED(pComponentDataObject->UpdateVerbState(this)));
  238. if (m_nState != loading)
  239. {
  240. pComponentDataObject->UpdateResultPaneView(this);
  241. }
  242. }
  243. BOOL CDNSMTContainerNode::CanCloseSheets()
  244. {
  245. return (IDCANCEL != DNSMessageBox(IDS_MSG_CONT_CLOSE_SHEET, MB_OKCANCEL));
  246. }
  247. void CDNSMTContainerNode::OnHaveData(CObjBase* pObj, CComponentDataObject* pComponentDataObject)
  248. {
  249. CDNSMTContainerNode* p = dynamic_cast<CDNSMTContainerNode*>(pObj);
  250. ASSERT(p != NULL);
  251. if (p != NULL)
  252. {
  253. p->SetServerNode(GetServerNode());
  254. }
  255. AddChildToListAndUI(p, pComponentDataObject);
  256. pComponentDataObject->SetDescriptionBarText(this);
  257. }
  258. void CDNSMTContainerNode::OnError(DWORD dwErr)
  259. {
  260. if (dwErr == ERROR_MORE_DATA)
  261. {
  262. // need to pop message
  263. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  264. CString szFmt;
  265. szFmt.LoadString(IDS_MSG_QUERY_TOO_MANY_ITEMS);
  266. CString szMsg;
  267. szMsg.Format(szFmt, GetDisplayName());
  268. AfxMessageBox(szMsg);
  269. // this is actually a warning, need to reset
  270. dwErr = 0;
  271. }
  272. m_dwErr = dwErr;
  273. }
  274. ///////////////////////////////////////////////////////////////////////////////
  275. // CDNSQueryObj : general purpose base class
  276. void CDNSQueryObj::SetFilterOptions(CDNSQueryFilter* pFilter)
  277. {
  278. // limits
  279. m_bGetAll = pFilter->GetAll();
  280. m_nMaxObjectCount = pFilter->GetMaxObjectCount();
  281. // filtering
  282. m_nFilterOption = pFilter->GetFilterOption();
  283. m_szFilterString1 = pFilter->GetFilterString();
  284. m_nFilterStringLen1 = m_szFilterString1.GetLength();
  285. m_szFilterString2 = pFilter->GetFilterStringRange();
  286. m_nFilterStringLen2 = m_szFilterString2.GetLength();
  287. if ((m_nFilterStringLen1 == 0) && (m_nFilterStringLen2 == 0))
  288. m_nFilterOption = DNS_QUERY_FILTER_NONE;
  289. }
  290. BOOL CDNSQueryObj::MatchName(LPCWSTR lpszName)
  291. {
  292. if (m_nFilterOption == DNS_QUERY_FILTER_CONTAINS)
  293. {
  294. //
  295. // wcsstr is case sensitive so make the strings lower
  296. // case before trying to find the substring
  297. //
  298. CString szName = lpszName;
  299. CString szFilterString = m_szFilterString1;
  300. szName.MakeLower();
  301. szFilterString.MakeLower();
  302. LPWSTR lpsz = wcsstr((LPCWSTR)szName, (LPCWSTR)szFilterString);
  303. return (lpsz != NULL);
  304. }
  305. if (m_nFilterOption == DNS_QUERY_FILTER_STARTS)
  306. {
  307. // match at the beginning
  308. size_t nLen = wcslen(lpszName);
  309. if (static_cast<int>(nLen) < m_nFilterStringLen1)
  310. return FALSE; // too short
  311. return (_wcsnicmp(lpszName, (LPCWSTR)m_szFilterString1, m_nFilterStringLen1) == 0);
  312. }
  313. if (m_nFilterOption == DNS_QUERY_FILTER_RANGE)
  314. {
  315. // test lower limit
  316. if (m_nFilterStringLen1 > 0)
  317. {
  318. if (_wcsicmp(lpszName, (LPCWSTR)m_szFilterString1) < 0)
  319. return FALSE; // below range, no need to continue
  320. }
  321. // test upper limit
  322. if (m_nFilterStringLen2 > 0)
  323. {
  324. return _wcsnicmp(lpszName, (LPCWSTR)m_szFilterString2, m_nFilterStringLen2) <= 0;
  325. }
  326. return TRUE;
  327. }
  328. return TRUE;
  329. }
  330. BOOL CDNSQueryObj::TooMuchData()
  331. {
  332. if (m_bGetAll || (m_nObjectCount <= m_nMaxObjectCount))
  333. return FALSE;
  334. TRACE(_T("TooMuchData() m_nObjectCount = %d "), m_nObjectCount);
  335. /*
  336. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  337. CString szFmt;
  338. szFmt.LoadString(IDS_MSG_QUERY_TOO_MANY_ITEMS);
  339. CString szMsg;
  340. szMsg.Format(szFmt, lpszFolderName);
  341. AfxMessageBox(szMsg);
  342. */
  343. return TRUE;
  344. }
  345. /////////////////////////////////////////////////////////////////////////
  346. // CCathegoryFolderNode
  347. BOOL CCathegoryFolderQueryObj::CanAddZone(PDNS_RPC_ZONE pZoneInfo)
  348. {
  349. // no filtering if cache is selected
  350. if (m_type == cache)
  351. return TRUE;
  352. // no filtering on reverse lookup autocreated zones
  353. if ( (m_type == revAuthoritated) && (pZoneInfo->Flags.AutoCreated))
  354. return TRUE;
  355. // filter on name
  356. return MatchName(pZoneInfo->pszZoneName);
  357. }
  358. BOOL CCathegoryFolderQueryObj::Enumerate()
  359. {
  360. USES_CONVERSION;
  361. DWORD dwFilter = 0;
  362. switch(m_type)
  363. {
  364. case cache:
  365. dwFilter = ZONE_REQUEST_CACHE;
  366. m_bGetAll = TRUE; // no limit on #, to be safe
  367. break;
  368. case fwdAuthoritated:
  369. dwFilter = ZONE_REQUEST_FORWARD |
  370. ZONE_REQUEST_PRIMARY |
  371. ZONE_REQUEST_SECONDARY |
  372. ZONE_REQUEST_STUB;
  373. break;
  374. case revAuthoritated:
  375. dwFilter = ZONE_REQUEST_REVERSE |
  376. ZONE_REQUEST_PRIMARY |
  377. ZONE_REQUEST_SECONDARY |
  378. ZONE_REQUEST_STUB |
  379. ZONE_REQUEST_AUTO;
  380. break;
  381. case domainForwarders:
  382. dwFilter = ZONE_REQUEST_FORWARDER;
  383. break;
  384. }
  385. PDNS_RPC_ZONE_LIST pZoneList = NULL;
  386. DNS_STATUS err = ::DnssrvEnumZones(m_szServerName,
  387. dwFilter,
  388. NULL /*pszLastZone, unused for the moment */,
  389. &pZoneList);
  390. if (err != 0)
  391. {
  392. if (pZoneList != NULL)
  393. ::DnssrvFreeZoneList(pZoneList);
  394. OnError(err);
  395. return FALSE;
  396. }
  397. if (!pZoneList)
  398. {
  399. ASSERT(pZoneList);
  400. return FALSE;
  401. }
  402. for (DWORD iZone = 0; iZone < pZoneList->dwZoneCount; iZone++)
  403. {
  404. if (pZoneList->ZoneArray[iZone]->Flags.AutoCreated)
  405. {
  406. // if the zone is autocreated, we cannot count it in the
  407. // filtering limit, because we need it anyway
  408. m_nMaxObjectCount++;
  409. }
  410. else
  411. {
  412. if (TooMuchData())
  413. break;
  414. }
  415. //
  416. // Don't filter the domain forwarders
  417. //
  418. if (m_type != domainForwarders)
  419. {
  420. if (CanAddZone(pZoneList->ZoneArray[iZone]))
  421. {
  422. TRACE(_T("%s\n"),pZoneList->ZoneArray[iZone]->pszZoneName);
  423. CDNSZoneNode* pZoneNode = new CDNSZoneNode();
  424. if (pZoneNode != NULL)
  425. {
  426. pZoneNode->InitializeFromRPCZoneInfo(pZoneList->ZoneArray[iZone], m_bAdvancedView);
  427. VERIFY(AddQueryResult(pZoneNode));
  428. }
  429. }
  430. }
  431. else
  432. {
  433. TRACE(_T("%s\n"),pZoneList->ZoneArray[iZone]->pszZoneName);
  434. CDNSZoneNode* pZoneNode = new CDNSZoneNode();
  435. if (pZoneNode != NULL)
  436. {
  437. pZoneNode->InitializeFromRPCZoneInfo(pZoneList->ZoneArray[iZone], m_bAdvancedView);
  438. VERIFY(AddQueryResult(pZoneNode));
  439. }
  440. }
  441. }
  442. ::DnssrvFreeZoneList(pZoneList);
  443. return FALSE;
  444. }
  445. CQueryObj* CCathegoryFolderNode::OnCreateQuery()
  446. {
  447. CDNSRootData* pRootData = (CDNSRootData*)GetRootContainer();
  448. ASSERT(pRootData != NULL);
  449. ASSERT(m_type != CCathegoryFolderQueryObj::unk);
  450. CCathegoryFolderQueryObj* pQuery =
  451. new CCathegoryFolderQueryObj(pRootData->IsAdvancedView(),
  452. GetServerNode()->GetVersion());
  453. pQuery->m_szServerName = GetServerNode()->GetRPCName();
  454. pQuery->SetType(m_type);
  455. return pQuery;
  456. }
  457. HRESULT CCathegoryFolderNode::OnCommand(long nCommandID,
  458. DATA_OBJECT_TYPES,
  459. CComponentDataObject* pComponentData,
  460. CNodeList* pNodeList)
  461. {
  462. if (pNodeList->GetCount() > 1) // multiple selection
  463. {
  464. return E_FAIL;
  465. }
  466. if (nCommandID == IDM_SNAPIN_ADVANCED_VIEW)
  467. {
  468. ((CDNSRootData*)pComponentData->GetRootData())->OnViewOptions(pComponentData);
  469. pComponentData->UpdateResultPaneView(this);
  470. return S_OK;
  471. }
  472. if (nCommandID == IDM_SNAPIN_FILTERING)
  473. {
  474. if(((CDNSRootData*)pComponentData->GetRootData())->OnFilteringOptions(pComponentData))
  475. {
  476. pComponentData->SetDescriptionBarText(this);
  477. }
  478. return S_OK;
  479. }
  480. return E_FAIL;
  481. }
  482. BOOL CCathegoryFolderNode::OnAddMenuItem(LPCONTEXTMENUITEM2 pContextMenuItem2,
  483. long*)
  484. {
  485. if (pContextMenuItem2->lCommandID == IDM_SNAPIN_ADVANCED_VIEW)
  486. {
  487. pContextMenuItem2->fFlags = ((CDNSRootData*)GetRootContainer())->IsAdvancedView() ? MF_CHECKED : 0;
  488. }
  489. if (pContextMenuItem2->lCommandID == IDM_SNAPIN_FILTERING)
  490. {
  491. if (((CDNSRootData*)GetRootContainer())->IsFilteringEnabled())
  492. {
  493. pContextMenuItem2->fFlags = MF_CHECKED;
  494. }
  495. return TRUE;
  496. }
  497. return FALSE;
  498. }
  499. BOOL CCathegoryFolderNode::OnSetRefreshVerbState(DATA_OBJECT_TYPES,
  500. BOOL* pbHide,
  501. CNodeList*)
  502. {
  503. *pbHide = FALSE;
  504. return !IsThreadLocked();
  505. }
  506. LPWSTR CCathegoryFolderNode::GetDescriptionBarText()
  507. {
  508. static CString szFilterEnabled;
  509. static CString szZonesFormat;
  510. INT_PTR nContainerCount = GetContainerChildList()->GetCount();
  511. INT_PTR nLeafCount = GetLeafChildList()->GetCount();
  512. //
  513. // If not already loaded, then load the format string L"%d record(s)"
  514. //
  515. if (szZonesFormat.IsEmpty())
  516. {
  517. szZonesFormat.LoadString(IDS_FORMAT_ZONES);
  518. }
  519. //
  520. // Format the child count into the description bar text
  521. //
  522. m_szDescriptionBar.Format(szZonesFormat, nContainerCount + nLeafCount);
  523. //
  524. // Add L"[Filter Activated]" if the filter is on
  525. //
  526. if(((CDNSRootData*)GetRootContainer())->IsFilteringEnabled())
  527. {
  528. //
  529. // If not already loaded, then load the L"[Filter Activated]" string
  530. //
  531. if (szFilterEnabled.IsEmpty())
  532. {
  533. szFilterEnabled.LoadString(IDS_FILTER_ENABLED);
  534. }
  535. m_szDescriptionBar += szFilterEnabled;
  536. }
  537. return (LPWSTR)(LPCWSTR)m_szDescriptionBar;
  538. }
  539. /////////////////////////////////////////////////////////////////////////
  540. // CDNSCacheNode
  541. CDNSCacheNode::CDNSCacheNode()
  542. {
  543. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  544. m_type = CCathegoryFolderQueryObj::cache;
  545. m_dwNodeFlags |= TN_FLAG_NO_WRITE;
  546. m_szDisplayName.LoadString(IDS_CATHEGORY_FOLDER_CACHE);
  547. }
  548. BOOL CDNSCacheNode::OnAddMenuItem(LPCONTEXTMENUITEM2 pContextMenuItem2,
  549. long*)
  550. {
  551. //we have only one menu item, so no checks
  552. if (IsThreadLocked())
  553. {
  554. pContextMenuItem2->fFlags |= MF_GRAYED;
  555. }
  556. return TRUE;
  557. }
  558. HRESULT CDNSCacheNode::OnCommand(long nCommandID,
  559. DATA_OBJECT_TYPES,
  560. CComponentDataObject* pComponentData,
  561. CNodeList* pNodeList)
  562. {
  563. if (pNodeList->GetCount() > 1) // multiple selection
  564. {
  565. return E_FAIL;
  566. }
  567. switch (nCommandID)
  568. {
  569. case IDM_CACHE_FOLDER_CLEAR_CACHE:
  570. OnClearCache(pComponentData);
  571. break;
  572. default:
  573. ASSERT(FALSE); // Unknown command!
  574. return E_FAIL;
  575. }
  576. return S_OK;
  577. }
  578. void CDNSCacheNode::OnClearCache(CComponentDataObject* pComponentData)
  579. {
  580. ASSERT((GetFlags() & TN_FLAG_HIDDEN) == 0); // must not be hidden
  581. // if there are sheets up, ask to close them down, because
  582. // we will need a refresh
  583. if (IsSheetLocked())
  584. {
  585. if (!CanCloseSheets())
  586. return;
  587. pComponentData->GetPropertyPageHolderTable()->DeleteSheetsOfNode(this);
  588. }
  589. DNS_STATUS err;
  590. { // scope for the wait cursor
  591. CWaitCursor wait;
  592. err = GetServerNode()->ClearCache();
  593. }
  594. if (err != 0)
  595. {
  596. // need to let the user know the operation failed
  597. DNSErrorDialog(err, IDS_MSG_SERVER_FAIL_CLEAR_CACHE);
  598. return;
  599. }
  600. CNodeList nodeList;
  601. nodeList.AddTail(this);
  602. // the cache has been cleared, cause a refresh to get new data
  603. VERIFY(OnRefresh(pComponentData, &nodeList));
  604. }
  605. /////////////////////////////////////////////////////////////////////////
  606. // CDNSDomainForwardersNode
  607. //
  608. CDNSDomainForwardersNode::CDNSDomainForwardersNode()
  609. {
  610. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  611. m_type = CCathegoryFolderQueryObj::domainForwarders;
  612. //
  613. // Always hide the domain forwarders node
  614. //
  615. m_dwNodeFlags |= TN_FLAG_HIDDEN;
  616. m_szDisplayName.LoadString(IDS_CATHEGORY_FOLDER_DOMAIN_FORWARDERS);
  617. }
  618. BOOL CDNSDomainForwardersNode::OnEnumerate(CComponentDataObject* pComponentData, BOOL)
  619. {
  620. OnChangeState(pComponentData);
  621. VERIFY(StartBackgroundThread(pComponentData, FALSE));
  622. //
  623. // Now enumerate all the children
  624. //
  625. CNodeList* pContList = GetContainerChildList();
  626. if (pContList != NULL)
  627. {
  628. POSITION pos = pContList->GetHeadPosition();
  629. while (pos != NULL)
  630. {
  631. CDNSZoneNode* pZoneNode = reinterpret_cast<CDNSZoneNode*>(pContList->GetNext(pos));
  632. if (pZoneNode != NULL)
  633. {
  634. //
  635. // Enumerate the zone asynchronously
  636. //
  637. pZoneNode->OnEnumerate(pComponentData);
  638. }
  639. }
  640. }
  641. return FALSE;
  642. }
  643. /////////////////////////////////////////////////////////////////////////
  644. // CDNSAuthoritatedZonesNode
  645. BEGIN_TOOLBAR_MAP(CDNSAuthoritatedZonesNode)
  646. TOOLBAR_EVENT(toolbarNewZone, OnNewZone)
  647. END_TOOLBAR_MAP()
  648. CDNSAuthoritatedZonesNode::CDNSAuthoritatedZonesNode(BOOL bReverse, UINT nStringID)
  649. {
  650. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  651. m_szDisplayName.LoadString(nStringID);
  652. m_bReverse = bReverse;
  653. m_type = bReverse ? CCathegoryFolderQueryObj::revAuthoritated :
  654. CCathegoryFolderQueryObj::fwdAuthoritated;
  655. }
  656. HRESULT CDNSAuthoritatedZonesNode::OnSetToolbarVerbState(IToolbar* pToolbar,
  657. CNodeList* pNodeList)
  658. {
  659. HRESULT hr = S_OK;
  660. //
  661. // Set the button state for each button on the toolbar
  662. //
  663. hr = pToolbar->SetButtonState(toolbarNewServer, ENABLED, FALSE);
  664. ASSERT(SUCCEEDED(hr));
  665. hr = pToolbar->SetButtonState(toolbarNewRecord, ENABLED, FALSE);
  666. ASSERT(SUCCEEDED(hr));
  667. if (pNodeList->GetCount() > 1) // multiple selection
  668. {
  669. hr = pToolbar->SetButtonState(toolbarNewZone, ENABLED, FALSE);
  670. ASSERT(SUCCEEDED(hr));
  671. }
  672. else if (pNodeList->GetCount() == 1) // single selection
  673. {
  674. hr = pToolbar->SetButtonState(toolbarNewZone, ENABLED, (m_nState == loaded));
  675. ASSERT(SUCCEEDED(hr));
  676. }
  677. return hr;
  678. }
  679. HRESULT CDNSAuthoritatedZonesNode::OnCommand(long nCommandID,
  680. DATA_OBJECT_TYPES,
  681. CComponentDataObject* pComponentData,
  682. CNodeList* pNodeList)
  683. {
  684. HRESULT hr = S_OK;
  685. if (pNodeList->GetCount() > 1) // multiple selection
  686. {
  687. return E_FAIL;
  688. }
  689. switch (nCommandID)
  690. {
  691. case IDM_SERVER_NEW_ZONE:
  692. hr = OnNewZone(pComponentData, pNodeList);
  693. pComponentData->UpdateResultPaneView(this);
  694. break;
  695. case IDM_SNAPIN_ADVANCED_VIEW:
  696. ((CDNSRootData*)pComponentData->GetRootData())->OnViewOptions(pComponentData);
  697. pComponentData->UpdateResultPaneView(this);
  698. break;
  699. case IDM_SNAPIN_FILTERING:
  700. {
  701. if (((CDNSRootData*)pComponentData->GetRootData())->OnFilteringOptions(pComponentData))
  702. {
  703. pComponentData->SetDescriptionBarText(this);
  704. }
  705. }
  706. break;
  707. default:
  708. ASSERT(FALSE); // Unknown command!
  709. return E_FAIL;
  710. }
  711. return hr;
  712. };
  713. HRESULT CDNSAuthoritatedZonesNode::OnNewZone(CComponentDataObject* pComponentData, CNodeList*)
  714. {
  715. ASSERT(pComponentData != NULL);
  716. CDNSServerNode* pServerNode = GetServerNode();
  717. ASSERT(pServerNode != NULL);
  718. CDNSZoneWizardHolder holder(pComponentData);
  719. holder.Initialize(pServerNode);
  720. holder.PreSetZoneLookupType(!m_bReverse);
  721. holder.DoModalWizard();
  722. return S_OK;
  723. }
  724. BOOL CDNSAuthoritatedZonesNode::OnAddMenuItem(LPCONTEXTMENUITEM2 pContextMenuItem2,
  725. long*)
  726. {
  727. // gray out commands that need data from the server
  728. if ((m_nState != loaded) && (pContextMenuItem2->lCommandID == IDM_SERVER_NEW_ZONE))
  729. {
  730. pContextMenuItem2->fFlags |= MF_GRAYED;
  731. }
  732. // add toggle menu item for advanced view
  733. if (pContextMenuItem2->lCommandID == IDM_SNAPIN_ADVANCED_VIEW)
  734. {
  735. pContextMenuItem2->fFlags = ((CDNSRootData*)GetRootContainer())->IsAdvancedView() ? MF_CHECKED : 0;
  736. }
  737. if (pContextMenuItem2->lCommandID == IDM_SNAPIN_FILTERING)
  738. {
  739. if (((CDNSRootData*)GetRootContainer())->IsFilteringEnabled())
  740. {
  741. pContextMenuItem2->fFlags = MF_CHECKED;
  742. }
  743. return TRUE;
  744. }
  745. return TRUE;
  746. };
  747. BOOL CDNSAuthoritatedZonesNode::OnSetRefreshVerbState(DATA_OBJECT_TYPES,
  748. BOOL* pbHide,
  749. CNodeList*)
  750. {
  751. *pbHide = FALSE;
  752. return !IsThreadLocked();
  753. }
  754. /////////////////////////////////////////////////////////////////////////
  755. // CDNSForwardZonesNode
  756. CDNSForwardZonesNode::CDNSForwardZonesNode() :
  757. CDNSAuthoritatedZonesNode(FALSE, IDS_CATHEGORY_FOLDER_FWD)
  758. {
  759. }
  760. HRESULT CDNSForwardZonesNode::GetResultViewType(CComponentDataObject*,
  761. LPOLESTR *ppViewType,
  762. long *pViewOptions)
  763. {
  764. HRESULT hr = S_FALSE;
  765. if ((m_containerChildList.IsEmpty() &&
  766. m_leafChildList.IsEmpty()) ||
  767. m_nState == accessDenied ||
  768. m_nState == unableToLoad &&
  769. m_nState != loading &&
  770. m_nState != notLoaded)
  771. {
  772. *pViewOptions = MMC_VIEW_OPTIONS_NOLISTVIEWS;
  773. LPOLESTR psz = NULL;
  774. StringFromCLSID(CLSID_MessageView, &psz);
  775. USES_CONVERSION;
  776. if (psz != NULL)
  777. {
  778. *ppViewType = psz;
  779. hr = S_OK;
  780. }
  781. }
  782. else
  783. {
  784. *pViewOptions = MMC_VIEW_OPTIONS_MULTISELECT;
  785. *ppViewType = NULL;
  786. hr = S_FALSE;
  787. }
  788. return hr;
  789. }
  790. HRESULT CDNSForwardZonesNode::OnShow(LPCONSOLE lpConsole)
  791. {
  792. CComPtr<IUnknown> spUnknown;
  793. CComPtr<IMessageView> spMessageView;
  794. HRESULT hr = lpConsole->QueryResultView(&spUnknown);
  795. if (FAILED(hr))
  796. return S_OK;
  797. hr = spUnknown->QueryInterface(IID_IMessageView, (PVOID*)&spMessageView);
  798. if (SUCCEEDED(hr))
  799. {
  800. CString szTitle, szMessage;
  801. IconIdentifier iconID;
  802. if (m_nState == accessDenied)
  803. {
  804. VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_ACCESS_DENIED_TITLE));
  805. VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_ACCESS_DENIED_MESSAGE));
  806. iconID = Icon_Error;
  807. }
  808. else if (m_nState == unableToLoad)
  809. {
  810. VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_NOT_LOADED_TITLE));
  811. VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_NOT_LOADED_MESSAGE));
  812. iconID = Icon_Error;
  813. }
  814. else
  815. {
  816. VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_EMPTY_FOLDER_TITLE));
  817. VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_EMPTY_FOLDER_MESSAGE));
  818. iconID = Icon_Information;
  819. }
  820. spMessageView->SetTitleText(szTitle);
  821. spMessageView->SetBodyText(szMessage);
  822. spMessageView->SetIcon(iconID);
  823. }
  824. return S_OK;
  825. }
  826. /////////////////////////////////////////////////////////////////////////
  827. // CDNSReverseZonesNode
  828. CDNSReverseZonesNode::CDNSReverseZonesNode() :
  829. CDNSAuthoritatedZonesNode(TRUE, IDS_CATHEGORY_FOLDER_REV)
  830. {
  831. m_p0ZoneNode = NULL;
  832. m_p127ZoneNode = NULL;
  833. m_p255ZoneNode = NULL;
  834. }
  835. BOOL CDNSReverseZonesNode::OnRefresh(CComponentDataObject* pComponentData,
  836. CNodeList* pNodeList)
  837. {
  838. if (pNodeList->GetCount() > 1) // multiple selection
  839. {
  840. return FALSE;
  841. }
  842. if (CDNSAuthoritatedZonesNode::OnRefresh(pComponentData, pNodeList))
  843. {
  844. m_p0ZoneNode = NULL;
  845. m_p127ZoneNode = NULL;
  846. m_p255ZoneNode = NULL;
  847. return TRUE;
  848. }
  849. return FALSE;
  850. }
  851. void CDNSReverseZonesNode::OnHaveData(CObjBase* pObj, CComponentDataObject* pComponentDataObject)
  852. {
  853. // the autocreated zone nodes can be shown or not, depending on the view options
  854. if ( (m_p0ZoneNode == NULL) || (m_p127ZoneNode == NULL) || (m_p255ZoneNode == NULL) &&
  855. IS_CLASS(*pObj, CDNSZoneNode))
  856. {
  857. CDNSZoneNode* pZoneNode = dynamic_cast<CDNSZoneNode*>(pObj);
  858. ASSERT(pZoneNode != NULL); // should never have anything below but zones!!!
  859. if (pZoneNode != NULL)
  860. {
  861. CDNSRootData* pRootData = (CDNSRootData*)pComponentDataObject->GetRootData();
  862. if (pZoneNode->IsAutocreated())
  863. {
  864. BOOL bCachedPointer = FALSE;
  865. if (_wcsicmp(pZoneNode->GetFullName(), AUTOCREATED_0) == 0)
  866. {
  867. ASSERT(m_p0ZoneNode == NULL);
  868. m_p0ZoneNode = pZoneNode;
  869. bCachedPointer = TRUE;
  870. }
  871. else if (_wcsicmp(pZoneNode->GetFullName(), AUTOCREATED_127) == 0)
  872. {
  873. ASSERT(m_p127ZoneNode == NULL);
  874. m_p127ZoneNode = pZoneNode;
  875. bCachedPointer = TRUE;
  876. }
  877. else if (_wcsicmp(pZoneNode->GetFullName(), AUTOCREATED_255) == 0)
  878. {
  879. ASSERT(m_p255ZoneNode == NULL);
  880. m_p255ZoneNode = pZoneNode;
  881. bCachedPointer = TRUE;
  882. }
  883. if (bCachedPointer && !pRootData->IsAdvancedView())
  884. {
  885. pZoneNode->SetFlagsDown(TN_FLAG_HIDDEN,TRUE); // mark it hidden, will not be added to UI
  886. }
  887. }
  888. }
  889. }
  890. CDNSMTContainerNode::OnHaveData(pObj,pComponentDataObject);
  891. }
  892. void CDNSReverseZonesNode::ChangeViewOption(BOOL bAdvanced,
  893. CComponentDataObject* pComponentDataObject)
  894. {
  895. POSITION pos;
  896. for( pos = m_containerChildList.GetHeadPosition(); pos != NULL; )
  897. {
  898. CTreeNode* pCurrentChild = m_containerChildList.GetNext(pos);
  899. CDNSZoneNode* pZoneNode = dynamic_cast<CDNSZoneNode*>(pCurrentChild);
  900. ASSERT(pZoneNode != NULL);
  901. pZoneNode->ChangeViewOption(bAdvanced, pComponentDataObject);
  902. }
  903. if (m_p0ZoneNode != NULL)
  904. m_p0ZoneNode->Show(bAdvanced,pComponentDataObject);
  905. if (m_p127ZoneNode != NULL)
  906. m_p127ZoneNode->Show(bAdvanced,pComponentDataObject);
  907. if (m_p255ZoneNode != NULL)
  908. m_p255ZoneNode->Show(bAdvanced,pComponentDataObject);
  909. }
  910. HRESULT CDNSReverseZonesNode::GetResultViewType(CComponentDataObject*,
  911. LPOLESTR *ppViewType,
  912. long *pViewOptions)
  913. {
  914. HRESULT hr = S_FALSE;
  915. // the 3 refers to the auto-created reverse lookup zones
  916. if ((m_containerChildList.IsEmpty() &&
  917. m_leafChildList.IsEmpty()) ||
  918. (!((CDNSRootData*)GetRootContainer())->IsAdvancedView() && m_containerChildList.GetCount() == 3) ||
  919. m_nState == accessDenied ||
  920. m_nState == unableToLoad &&
  921. m_nState != loading &&
  922. m_nState != notLoaded)
  923. {
  924. *pViewOptions = MMC_VIEW_OPTIONS_NOLISTVIEWS;
  925. LPOLESTR psz = NULL;
  926. StringFromCLSID(CLSID_MessageView, &psz);
  927. USES_CONVERSION;
  928. if (psz != NULL)
  929. {
  930. *ppViewType = psz;
  931. hr = S_OK;
  932. }
  933. }
  934. else
  935. {
  936. *pViewOptions = MMC_VIEW_OPTIONS_MULTISELECT;
  937. *ppViewType = NULL;
  938. hr = S_FALSE;
  939. }
  940. return hr;
  941. }
  942. HRESULT CDNSReverseZonesNode::OnShow(LPCONSOLE lpConsole)
  943. {
  944. CComPtr<IUnknown> spUnknown;
  945. CComPtr<IMessageView> spMessageView;
  946. HRESULT hr = lpConsole->QueryResultView(&spUnknown);
  947. if (FAILED(hr))
  948. return S_OK;
  949. hr = spUnknown->QueryInterface(IID_IMessageView, (PVOID*)&spMessageView);
  950. if (SUCCEEDED(hr))
  951. {
  952. CString szTitle, szMessage;
  953. IconIdentifier iconID;
  954. if (m_nState == accessDenied)
  955. {
  956. VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_ACCESS_DENIED_TITLE));
  957. VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_ACCESS_DENIED_MESSAGE));
  958. iconID = Icon_Error;
  959. }
  960. else if (m_nState == unableToLoad)
  961. {
  962. VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_NOT_LOADED_TITLE));
  963. VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_NOT_LOADED_MESSAGE));
  964. iconID = Icon_Error;
  965. }
  966. else
  967. {
  968. VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_EMPTY_FOLDER_TITLE));
  969. VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_EMPTY_FOLDER_MESSAGE));
  970. iconID = Icon_Information;
  971. }
  972. spMessageView->SetTitleText(szTitle);
  973. spMessageView->SetBodyText(szMessage);
  974. spMessageView->SetIcon(iconID);
  975. }
  976. return S_OK;
  977. }
  978. /////////////////////////////////////////////////////////////////////////
  979. // CDNSServerTestOptions
  980. CDNSServerTestOptions::CDNSServerTestOptions()
  981. {
  982. m_bEnabled = FALSE;
  983. m_dwInterval = DEFAULT_SERVER_TEST_INTERVAL;
  984. m_bSimpleQuery = FALSE;
  985. m_bRecursiveQuery = FALSE;
  986. }
  987. HRESULT CDNSServerTestOptions::Save(IStream* pStm)
  988. {
  989. ULONG cbWrite;
  990. VERIFY(SUCCEEDED(pStm->Write((void*)&m_bEnabled, sizeof(BOOL),&cbWrite)));
  991. ASSERT(cbWrite == sizeof(BOOL));
  992. VERIFY(SUCCEEDED(pStm->Write((void*)&m_dwInterval, sizeof(DWORD),&cbWrite)));
  993. ASSERT(cbWrite == sizeof(DWORD));
  994. VERIFY(SUCCEEDED(pStm->Write((void*)&m_bSimpleQuery, sizeof(BOOL),&cbWrite)));
  995. ASSERT(cbWrite == sizeof(BOOL));
  996. VERIFY(SUCCEEDED(pStm->Write((void*)&m_bRecursiveQuery, sizeof(BOOL),&cbWrite)));
  997. ASSERT(cbWrite == sizeof(BOOL));
  998. return S_OK;
  999. }
  1000. HRESULT CDNSServerTestOptions::Load(IStream* pStm)
  1001. {
  1002. ULONG cbRead;
  1003. VERIFY(SUCCEEDED(pStm->Read((void*)&m_bEnabled,sizeof(BOOL), &cbRead)));
  1004. ASSERT(cbRead == sizeof(BOOL));
  1005. VERIFY(SUCCEEDED(pStm->Read((void*)&m_dwInterval,sizeof(DWORD), &cbRead)));
  1006. ASSERT(cbRead == sizeof(DWORD));
  1007. VERIFY(SUCCEEDED(pStm->Read((void*)&m_bSimpleQuery,sizeof(BOOL), &cbRead)));
  1008. ASSERT(cbRead == sizeof(BOOL));
  1009. VERIFY(SUCCEEDED(pStm->Read((void*)&m_bRecursiveQuery,sizeof(BOOL), &cbRead)));
  1010. ASSERT(cbRead == sizeof(BOOL));
  1011. // force range on test interval
  1012. if (m_dwInterval < MIN_SERVER_TEST_INTERVAL)
  1013. m_dwInterval = MIN_SERVER_TEST_INTERVAL;
  1014. else if (m_dwInterval > MAX_SERVER_TEST_INTERVAL)
  1015. m_dwInterval = MAX_SERVER_TEST_INTERVAL;
  1016. return S_OK;
  1017. }
  1018. const CDNSServerTestOptions&
  1019. CDNSServerTestOptions::operator=(const CDNSServerTestOptions& x)
  1020. {
  1021. m_bEnabled = x.m_bEnabled;
  1022. m_dwInterval = x.m_dwInterval;
  1023. m_bSimpleQuery = x.m_bSimpleQuery;
  1024. m_bRecursiveQuery = x.m_bRecursiveQuery;
  1025. return *this;
  1026. }
  1027. BOOL CDNSServerTestOptions::operator==(const CDNSServerTestOptions& x) const
  1028. {
  1029. if (m_bEnabled != x.m_bEnabled) return FALSE;
  1030. if (m_dwInterval != x.m_dwInterval) return FALSE;
  1031. if (m_bSimpleQuery != x.m_bSimpleQuery) return FALSE;
  1032. if (m_bRecursiveQuery != x.m_bRecursiveQuery) return FALSE;
  1033. return TRUE;
  1034. }
  1035. /////////////////////////////////////////////////////////////////////////
  1036. // CDNSServerNode
  1037. BEGIN_TOOLBAR_MAP(CDNSServerNode)
  1038. TOOLBAR_EVENT(toolbarNewZone, OnNewZone)
  1039. END_TOOLBAR_MAP()
  1040. // {720132B8-44B2-11d1-B92F-00A0C9A06D2D}
  1041. const GUID CDNSServerNode::NodeTypeGUID =
  1042. { 0x720132b8, 0x44b2, 0x11d1, { 0xb9, 0x2f, 0x0, 0xa0, 0xc9, 0xa0, 0x6d, 0x2d } };
  1043. CDNSServerNode::CDNSServerNode(LPCTSTR lpszName, BOOL bIsLocalServer)
  1044. {
  1045. SetServerNode(this);
  1046. m_szDisplayName = lpszName;
  1047. m_pServInfoEx = new CDNSServerInfoEx;
  1048. m_pRootHintsNode = NULL;
  1049. m_pCacheFolderNode = NULL;
  1050. m_pFwdZonesFolderNode = NULL;
  1051. m_pRevZonesFolderNode = NULL;
  1052. m_pDomainForwardersFolderNode = NULL;
  1053. m_dwTestTime = 0x0;
  1054. m_bTestQueryPending = FALSE;
  1055. m_bShowMessages = TRUE;
  1056. m_bPrevQuerySuccess = TRUE;
  1057. m_nStartProppage = -1;
  1058. m_bLocalServer = bIsLocalServer;
  1059. }
  1060. CDNSServerNode::~CDNSServerNode()
  1061. {
  1062. ASSERT(m_pServInfoEx != NULL);
  1063. delete m_pServInfoEx;
  1064. FreeRootHints();
  1065. //TRACE(_T("~CDNSServerNode(), name <%s>\n"),GetDisplayName());
  1066. }
  1067. void CDNSServerNode::SetDisplayName(LPCWSTR lpszDisplayName)
  1068. {
  1069. m_szDisplayName = lpszDisplayName;
  1070. }
  1071. LPCWSTR CDNSServerNode::GetRPCName()
  1072. {
  1073. return GetDisplayName();
  1074. }
  1075. CLIPFORMAT g_cfMachineName = (CLIPFORMAT)RegisterClipboardFormat(L"MMC_SNAPIN_MACHINE_NAME");
  1076. CLIPFORMAT g_cfServiceName = (CLIPFORMAT)RegisterClipboardFormat(L"FILEMGMT_SNAPIN_SERVICE_NAME");
  1077. CLIPFORMAT g_cfServiceDisplayName = (CLIPFORMAT)RegisterClipboardFormat(L"FILEMGMT_SNAPIN_SERVICE_DISPLAYNAME");
  1078. CLIPFORMAT g_cfFramewrkDataObjectType = (CLIPFORMAT)RegisterClipboardFormat(L"FRAMEWRK_DATA_OBJECT_TYPE");
  1079. CLIPFORMAT g_cfEventViewer = (CLIPFORMAT)RegisterClipboardFormat(L"CF_EV_VIEWS");
  1080. HRESULT CDNSServerNode::GetDataHere(CLIPFORMAT cf, LPSTGMEDIUM lpMedium,
  1081. CDataObject* pDataObject)
  1082. {
  1083. ASSERT(pDataObject != NULL);
  1084. HRESULT hr = DV_E_CLIPFORMAT;
  1085. if (cf == g_cfMachineName)
  1086. {
  1087. LPCWSTR pwszMachineName = GetDisplayName();
  1088. hr = pDataObject->Create(pwszMachineName, BYTE_MEM_LEN_W(pwszMachineName), lpMedium);
  1089. }
  1090. else if (cf == g_cfServiceName)
  1091. {
  1092. LPCWSTR pwszServiceName = _T("DNS");
  1093. hr = pDataObject->Create(pwszServiceName, BYTE_MEM_LEN_W(pwszServiceName), lpMedium);
  1094. }
  1095. else if (cf == g_cfServiceDisplayName)
  1096. {
  1097. LPCWSTR pwszServiceDisplayName = _T("Microsoft DNS Server");
  1098. hr = pDataObject->Create(pwszServiceDisplayName, BYTE_MEM_LEN_W(pwszServiceDisplayName), lpMedium);
  1099. }
  1100. else if (cf == g_cfFramewrkDataObjectType)
  1101. {
  1102. DATA_OBJECT_TYPES type = pDataObject->GetType();
  1103. hr = pDataObject->Create(&type, sizeof(DATA_OBJECT_TYPES), lpMedium);
  1104. }
  1105. return hr;
  1106. }
  1107. HRESULT CDNSServerNode::GetData(CLIPFORMAT cf, LPSTGMEDIUM lpMedium, CDataObject* pDataObject)
  1108. {
  1109. ASSERT(pDataObject != NULL);
  1110. HRESULT hr = DV_E_CLIPFORMAT;
  1111. if (cf == g_cfEventViewer)
  1112. {
  1113. hr = RetrieveEventViewerLogs(lpMedium, pDataObject);
  1114. }
  1115. return hr;
  1116. }
  1117. //
  1118. // Macros and #defines for event viewer clipformats
  1119. //
  1120. #define ELT_SYSTEM 101
  1121. #define ELT_SECURITY 102
  1122. #define ELT_APPLICATION 103
  1123. #define ELT_CUSTOM 104
  1124. #define VIEWINFO_BACKUP 0x0001
  1125. #define VIEWINFO_FILTERED 0x0002
  1126. #define VIEWINFO_LOW_SPEED 0x0004
  1127. #define VIEWINFO_USER_CREATED 0x0008
  1128. #define VIEWINFO_ALLOW_DELETE 0x0100
  1129. #define VIEWINFO_DISABLED 0x0200
  1130. #define VIEWINFO_READ_ONLY 0x0400
  1131. #define VIEWINFO_DONT_PERSIST 0x0800
  1132. #define VIEWINFO_CUSTOM ( VIEWINFO_FILTERED | VIEWINFO_DONT_PERSIST | \
  1133. VIEWINFO_ALLOW_DELETE | VIEWINFO_USER_CREATED)
  1134. #define EV_ALL_ERRORS (EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | \
  1135. EVENTLOG_INFORMATION_TYPE | EVENTLOG_AUDIT_SUCCESS | \
  1136. EVENTLOG_AUDIT_FAILURE)
  1137. // Make sure that the data is processor aligned
  1138. #if defined(_X86_)
  1139. #define _RNDUP(p,m) (p)
  1140. #else
  1141. #define _RNDUP(p,m) (BYTE *)(((ULONG_PTR)(p) + (m) - 1) & ~((m) - 1))
  1142. #endif
  1143. #define ADD_TYPE(data, type) \
  1144. pPos = _RNDUP(pPos, (ULONG_PTR) __alignof(type)); \
  1145. *((type*)pPos) = (type)(data); \
  1146. pPos += sizeof(type)
  1147. #define ADD_USHORT(us) ADD_TYPE(us, USHORT)
  1148. #define ADD_BOOL(b) ADD_TYPE(b, BOOL)
  1149. #define ADD_ULONG(ul) ADD_TYPE(ul, ULONG)
  1150. #define ADD_STRING(str) \
  1151. strLength = wcslen((LPCWSTR)(str)) + 1; \
  1152. ADD_USHORT(strLength); \
  1153. wcsncpy((LPWSTR)pPos, (LPCWSTR)(str), strLength); \
  1154. pPos += strLength * sizeof(WCHAR);
  1155. HRESULT CDNSServerNode::RetrieveEventViewerLogs(LPSTGMEDIUM lpMedium, CDataObject*)
  1156. {
  1157. HRESULT hr = S_OK;
  1158. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1159. HGLOBAL hMem = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, 1024 );
  1160. if( NULL == hMem )
  1161. {
  1162. return STG_E_MEDIUMFULL;
  1163. }
  1164. //
  1165. // Get a pointer to our data
  1166. //
  1167. BYTE* pPos = reinterpret_cast<BYTE*>(::GlobalLock(hMem));
  1168. if (!pPos)
  1169. {
  1170. return HRESULT_FROM_WIN32(GetLastError());
  1171. }
  1172. size_t strLength = 0;
  1173. //
  1174. // Build the path to the event log
  1175. //
  1176. CString szDNSEventPath;
  1177. CString szConfigPath;
  1178. CString szServerName = L"\\\\";
  1179. szServerName += GetDisplayName();
  1180. szConfigPath += szServerName;
  1181. szConfigPath += L"\\Admin$\\System32\\config\\";
  1182. szDNSEventPath = szConfigPath;
  1183. szDNSEventPath += L"DNSEvent.Evt";
  1184. //
  1185. // Add header info
  1186. //
  1187. ADD_BOOL( TRUE ); // fOnlyTheseViews
  1188. ADD_USHORT( 1 ); // cViews
  1189. //
  1190. // Add application log filtered for our services
  1191. //
  1192. ADD_ULONG( ELT_CUSTOM ); // Type; ELT_CUSTOM
  1193. ADD_USHORT( VIEWINFO_CUSTOM ); // flViewFlags: VIEWINFO_FILTERED
  1194. ADD_STRING( GetDisplayName() ); // ServerName
  1195. ADD_STRING( L"DNS Server" ); // SourceName
  1196. ADD_STRING( szDNSEventPath ); // FileName
  1197. ADD_STRING( L"DNS Events" ); // DisplayName REVIEW_JEFFJON : this needs to be put in the rc file
  1198. ADD_ULONG( EV_ALL_ERRORS );// flRecType (could filter warning, error, etc.)
  1199. ADD_USHORT( 0 ); // usCategory
  1200. ADD_BOOL( FALSE ); // fEventID
  1201. ADD_ULONG( 0 ); // ulEventID
  1202. ADD_STRING( L"" ); // szSourceName
  1203. ADD_STRING( L"" ); // szUser
  1204. ADD_STRING( L"" ); // szComputer
  1205. ADD_ULONG( 0 ); // ulFrom
  1206. ADD_ULONG( 0 ); // ulTo
  1207. ::GlobalUnlock( hMem ); // Unlock and set the rest of the
  1208. lpMedium->hGlobal = hMem; // StgMedium variables
  1209. lpMedium->tymed = TYMED_HGLOBAL;
  1210. lpMedium->pUnkForRelease = NULL;
  1211. return hr;
  1212. }
  1213. void CDNSServerNode::ChangeViewOption(BOOL bAdvanced, CComponentDataObject* pComponentData)
  1214. {
  1215. //
  1216. // changes in record options
  1217. //
  1218. SetFlagsOnNonContainers(TN_FLAG_DNS_RECORD_FULL_NAME , !bAdvanced);
  1219. //
  1220. //pComponentData->RepaintResultPane(this);
  1221. //
  1222. pComponentData->RepaintSelectedFolderInResultPane();
  1223. //
  1224. // Cached Lookup Folder
  1225. //
  1226. if (m_pCacheFolderNode != NULL)
  1227. {
  1228. m_pCacheFolderNode->Show(bAdvanced,pComponentData);
  1229. }
  1230. //
  1231. // Auto Created Zones
  1232. //
  1233. if (m_pRevZonesFolderNode != NULL)
  1234. {
  1235. m_pRevZonesFolderNode->ChangeViewOption(bAdvanced, pComponentData);
  1236. }
  1237. }
  1238. CDNSAuthoritatedZonesNode* CDNSServerNode::GetAuthoritatedZoneFolder(BOOL bFwd)
  1239. {
  1240. return bFwd ? (CDNSAuthoritatedZonesNode*)m_pFwdZonesFolderNode :
  1241. (CDNSAuthoritatedZonesNode*)m_pRevZonesFolderNode;
  1242. }
  1243. HRESULT CDNSServerNode::OnSetToolbarVerbState(IToolbar* pToolbar,
  1244. CNodeList* pNodeList)
  1245. {
  1246. HRESULT hr = S_OK;
  1247. //
  1248. // Set the button state for each button on the toolbar
  1249. //
  1250. hr = pToolbar->SetButtonState(toolbarNewServer, ENABLED, FALSE);
  1251. ASSERT(SUCCEEDED(hr));
  1252. hr = pToolbar->SetButtonState(toolbarNewRecord, ENABLED, FALSE);
  1253. ASSERT(SUCCEEDED(hr));
  1254. if (pNodeList->GetCount() > 1) // multiple selection
  1255. {
  1256. hr = pToolbar->SetButtonState(toolbarNewZone, ENABLED, FALSE);
  1257. ASSERT(SUCCEEDED(hr));
  1258. }
  1259. else if (pNodeList->GetCount() == 1) // single selection
  1260. {
  1261. hr = pToolbar->SetButtonState(toolbarNewZone, ENABLED, (m_nState == loaded));
  1262. }
  1263. return hr;
  1264. }
  1265. HRESULT CDNSServerNode::OnCommand(long nCommandID,
  1266. DATA_OBJECT_TYPES,
  1267. CComponentDataObject* pComponentData,
  1268. CNodeList* pNodeList)
  1269. {
  1270. HRESULT hr = S_OK;
  1271. if (pNodeList->GetCount() == 1) // single selection
  1272. {
  1273. switch (nCommandID)
  1274. {
  1275. case IDM_SERVER_NEW_ZONE:
  1276. hr = OnNewZone(pComponentData, pNodeList);
  1277. break;
  1278. case IDM_SERVER_UPDATE_DATA_FILES:
  1279. OnUpdateDataFiles(pComponentData);
  1280. break;
  1281. case IDM_SERVER_CLEAR_CACHE:
  1282. OnClearCache(pComponentData);
  1283. break;
  1284. case IDM_SNAPIN_ADVANCED_VIEW:
  1285. ((CDNSRootData*)pComponentData->GetRootData())->OnViewOptions(pComponentData);
  1286. break;
  1287. case IDM_SNAPIN_MESSAGE:
  1288. m_bShowMessages = !m_bShowMessages;
  1289. pComponentData->UpdateResultPaneView(this);
  1290. break;
  1291. case IDM_SNAPIN_FILTERING:
  1292. {
  1293. if (((CDNSRootData*)pComponentData->GetRootData())->OnFilteringOptions(pComponentData))
  1294. {
  1295. pComponentData->SetDescriptionBarText(this);
  1296. }
  1297. }
  1298. break;
  1299. case IDM_SERVER_SET_AGING:
  1300. SetRecordAging();
  1301. break;
  1302. case IDM_SERVER_SCAVENGE:
  1303. ScavengeRecords();
  1304. break;
  1305. case IDM_SERVER_CONFIGURE:
  1306. OnConfigureServer(pComponentData);
  1307. break;
  1308. #ifdef USE_NDNC
  1309. case IDM_SERVER_CREATE_NDNC:
  1310. OnCreateNDNC();
  1311. break;
  1312. #endif
  1313. default:
  1314. ASSERT(FALSE); // Unknown command!
  1315. hr = E_FAIL;
  1316. }
  1317. }
  1318. else
  1319. {
  1320. hr = E_FAIL;
  1321. }
  1322. return hr;
  1323. }
  1324. #ifdef USE_NDNC
  1325. void CDNSServerNode::OnCreateNDNC()
  1326. {
  1327. // First ask if they want to create the domain NDNC
  1328. USES_CONVERSION;
  1329. do
  1330. {
  1331. DNS_STATUS err = 0;
  1332. CString szDomainNDNC;
  1333. szDomainNDNC.Format(IDS_SERVER_CREATE_DOMAIN_NDNC_FORMAT, UTF8_TO_W(GetDomainName()));
  1334. UINT nResult = DNSMessageBox(szDomainNDNC, MB_YESNOCANCEL | MB_ICONWARNING);
  1335. if (IDCANCEL == nResult)
  1336. {
  1337. // don't do anything more
  1338. break;
  1339. }
  1340. else if (IDYES == nResult)
  1341. {
  1342. // create the domain partition
  1343. err = ::DnssrvSetupDefaultDirectoryPartitions(
  1344. GetRPCName(),
  1345. DNS_DP_OP_CREATE_DOMAIN);
  1346. if (err != 0)
  1347. {
  1348. DNSErrorDialog(err, IDS_ERRMSG_CREATE_DOMAIN_NDNC);
  1349. break;
  1350. }
  1351. }
  1352. CString szForestNDNC;
  1353. szForestNDNC.Format(IDS_SERVER_CREATE_FOREST_NDNC_FORMAT, UTF8_TO_W(GetForestName()));
  1354. nResult = DNSMessageBox(szForestNDNC, MB_YESNO | MB_ICONWARNING);
  1355. if (IDYES == nResult)
  1356. {
  1357. // create the forest partition
  1358. err = ::DnssrvSetupDefaultDirectoryPartitions(
  1359. GetRPCName(),
  1360. DNS_DP_OP_CREATE_FOREST);
  1361. if (err != 0)
  1362. {
  1363. DNSErrorDialog(err, IDS_ERRMSG_CREATE_FOREST_NDNC);
  1364. break;
  1365. }
  1366. }
  1367. } while (false);
  1368. }
  1369. #endif // USE_NDNC
  1370. void CDNSServerNode::OnConfigureServer(CComponentDataObject* pComponentData)
  1371. {
  1372. CDNSServerWizardHolder holder((CDNSRootData*)GetRootContainer(), pComponentData, this);
  1373. holder.DoModalWizard();
  1374. pComponentData->UpdateResultPaneView(this);
  1375. }
  1376. void CDNSServerNode::SetRecordAging()
  1377. {
  1378. CDNSZone_AgingDialog dlg(NULL, IDD_SERVER_AGING_DIALOG, ((CDNSRootData*)GetRootContainer())->GetComponentDataObject());
  1379. dlg.m_dwRefreshInterval = GetDefaultRefreshInterval();
  1380. dlg.m_dwNoRefreshInterval = GetDefaultNoRefreshInterval();
  1381. dlg.m_fScavengingEnabled = GetDefaultScavengingState();
  1382. dlg.m_dwDefaultRefreshInterval = GetDefaultRefreshInterval();
  1383. dlg.m_dwDefaultNoRefreshInterval = GetDefaultNoRefreshInterval();
  1384. dlg.m_bDefaultScavengingState = GetDefaultScavengingState();
  1385. if (IDCANCEL == dlg.DoModal())
  1386. {
  1387. return;
  1388. }
  1389. DNS_STATUS dwErr;
  1390. if (dlg.m_dwRefreshInterval != GetDefaultRefreshInterval())
  1391. {
  1392. dwErr = ResetDefaultRefreshInterval(dlg.m_dwRefreshInterval);
  1393. if (dwErr != 0)
  1394. {
  1395. DNSErrorDialog(dwErr, IDS_MSG_SERVER_UPDATE_AGING);
  1396. return;
  1397. }
  1398. }
  1399. if (dlg.m_dwNoRefreshInterval != GetDefaultNoRefreshInterval())
  1400. {
  1401. dwErr = ResetDefaultNoRefreshInterval(dlg.m_dwNoRefreshInterval);
  1402. if (dwErr != 0)
  1403. {
  1404. DNSErrorDialog(dwErr, IDS_MSG_SERVER_UPDATE_AGING);
  1405. return;
  1406. }
  1407. }
  1408. if (dlg.m_fScavengingEnabled != GetDefaultScavengingState())
  1409. {
  1410. DWORD dwScavengingState = DNS_AGING_OFF;
  1411. if (dlg.m_fScavengingEnabled)
  1412. {
  1413. dwScavengingState = DNS_AGING_DS_ZONES;
  1414. }
  1415. dwErr = ResetDefaultScavengingState(dwScavengingState);
  1416. if (dwErr != 0)
  1417. {
  1418. DNSErrorDialog(dwErr, IDS_MSG_SERVER_UPDATE_AGING);
  1419. return;
  1420. }
  1421. }
  1422. BOOL bApplyAll = dlg.m_bADApplyAll;
  1423. if (bApplyAll)
  1424. {
  1425. DWORD dwContextFlags = ZONE_REQUEST_PRIMARY;
  1426. dwContextFlags = dlg.m_bADApplyAll ? dwContextFlags | ZONE_REQUEST_DS : dwContextFlags;
  1427. if (dlg.m_bNoRefreshDirty)
  1428. {
  1429. dwErr = ::DnssrvResetDwordPropertyWithContext(GetRPCName(),
  1430. DNS_ZONE_ALL,
  1431. dwContextFlags,
  1432. DNS_REGKEY_ZONE_NOREFRESH_INTERVAL,
  1433. dlg.m_dwNoRefreshInterval);
  1434. if (dwErr != 0)
  1435. {
  1436. DNSErrorDialog(dwErr, IDS_MSG_SERVER_UPDATE_AGING);
  1437. return;
  1438. }
  1439. }
  1440. if (dlg.m_bRefreshDirty)
  1441. {
  1442. dwErr = ::DnssrvResetDwordPropertyWithContext(GetRPCName(),
  1443. DNS_ZONE_ALL,
  1444. dwContextFlags,
  1445. DNS_REGKEY_ZONE_REFRESH_INTERVAL,
  1446. dlg.m_dwRefreshInterval);
  1447. if (dwErr != 0)
  1448. {
  1449. DNSErrorDialog(dwErr, IDS_MSG_SERVER_UPDATE_AGING);
  1450. return;
  1451. }
  1452. }
  1453. if (dlg.m_bScavengeDirty)
  1454. {
  1455. dwErr = ::DnssrvResetDwordPropertyWithContext(GetRPCName(),
  1456. DNS_ZONE_ALL,
  1457. dwContextFlags,
  1458. DNS_REGKEY_ZONE_AGING,
  1459. dlg.m_fScavengingEnabled);
  1460. if (dwErr != 0)
  1461. {
  1462. DNSErrorDialog(dwErr, IDS_MSG_SERVER_UPDATE_AGING);
  1463. return;
  1464. }
  1465. }
  1466. }
  1467. }
  1468. void CDNSServerNode::ScavengeRecords()
  1469. {
  1470. UINT nRet = DNSConfirmOperation(IDS_MSG_SERVER_CONFIRM_SCAVENGE, this);
  1471. if(IDCANCEL == nRet ||
  1472. IDNO == nRet)
  1473. {
  1474. return;
  1475. }
  1476. DNS_STATUS dwErr = ::DnssrvOperation(GetRPCName(),
  1477. NULL,
  1478. DNSSRV_OP_START_SCAVENGING,
  1479. DNSSRV_TYPEID_NULL,
  1480. NULL);
  1481. if (dwErr != 0)
  1482. {
  1483. DNSErrorDialog(dwErr, IDS_MSG_ERROR_SCAVENGE_RECORDS);
  1484. return;
  1485. }
  1486. }
  1487. int CDNSServerNode::GetImageIndex(BOOL)
  1488. {
  1489. BOOL bSuccess = m_testResultList.LastQuerySuceeded();
  1490. int nIndex = 0;
  1491. switch (m_nState)
  1492. {
  1493. case notLoaded:
  1494. nIndex = bSuccess ? SERVER_IMAGE_NOT_LOADED : SERVER_IMAGE_NOT_LOADED_TEST_FAIL;
  1495. break;
  1496. case loading:
  1497. nIndex = bSuccess ? SERVER_IMAGE_LOADING : SERVER_IMAGE_LOADING_TEST_FAIL;
  1498. break;
  1499. case loaded:
  1500. nIndex = bSuccess ? SERVER_IMAGE_LOADED : SERVER_IMAGE_LOADED_TEST_FAIL;
  1501. break;
  1502. case unableToLoad:
  1503. nIndex = bSuccess ? SERVER_IMAGE_UNABLE_TO_LOAD : SERVER_IMAGE_UNABLE_TO_LOAD_TEST_FAIL;
  1504. break;
  1505. case accessDenied:
  1506. nIndex = bSuccess ? SERVER_IMAGE_ACCESS_DENIED : SERVER_IMAGE_ACCESS_DENIED_TEST_FAIL;
  1507. break;
  1508. default:
  1509. ASSERT(FALSE);
  1510. }
  1511. return nIndex;
  1512. }
  1513. void CDNSServerNode::OnDelete(CComponentDataObject* pComponentData,
  1514. CNodeList* pNodeList)
  1515. {
  1516. if (pNodeList->GetCount() > 1) // multiple selection
  1517. {
  1518. return;
  1519. }
  1520. UINT nRet = DNSConfirmOperation(IDS_MSG_SERVER_DELETE, this);
  1521. if (IDCANCEL == nRet ||
  1522. IDNO == nRet)
  1523. {
  1524. return;
  1525. }
  1526. if (IsSheetLocked())
  1527. {
  1528. if (!CanCloseSheets())
  1529. return;
  1530. pComponentData->GetPropertyPageHolderTable()->DeleteSheetsOfNode(this);
  1531. }
  1532. ASSERT(!IsSheetLocked());
  1533. // now remove from the UI and from the cache
  1534. DeleteHelper(pComponentData);
  1535. CDNSRootData* pSnapinData = (CDNSRootData*)GetRootContainer();
  1536. pSnapinData->SetDirtyFlag(TRUE);
  1537. pSnapinData->RemoveServerFromThreadList(this, pComponentData);
  1538. pComponentData->UpdateResultPaneView(GetContainer());
  1539. delete this; // gone
  1540. }
  1541. #define MAX_COMPUTER_DISPLAYNAME_LENGTH 256
  1542. HRESULT CDNSServerNode::CreateFromStream(IStream* pStm, CDNSServerNode** ppServerNode)
  1543. {
  1544. WCHAR szBuffer[MAX_COMPUTER_DISPLAYNAME_LENGTH];
  1545. ULONG nLen; // WCHAR counting NULL
  1546. ULONG cbRead;
  1547. VERIFY(SUCCEEDED(pStm->Read((void*)&nLen,sizeof(UINT), &cbRead)));
  1548. ASSERT(cbRead == sizeof(UINT));
  1549. VERIFY(SUCCEEDED(pStm->Read((void*)szBuffer,sizeof(WCHAR)*nLen, &cbRead)));
  1550. ASSERT(cbRead == sizeof(WCHAR)*nLen);
  1551. BOOL bIsLocalHost = (_wcsicmp(szBuffer, L"localhost.") == 0);
  1552. if (bIsLocalHost)
  1553. {
  1554. //
  1555. // Retrieve the local computer name
  1556. //
  1557. DWORD dwLen = MAX_COMPUTER_DISPLAYNAME_LENGTH;
  1558. BOOL bRes = ::GetComputerName(szBuffer, &dwLen);
  1559. ASSERT(bRes);
  1560. }
  1561. *ppServerNode = new CDNSServerNode(szBuffer, bIsLocalHost);
  1562. ASSERT(*ppServerNode != NULL);
  1563. VERIFY(SUCCEEDED((*ppServerNode)->m_testOptions.Load(pStm)));
  1564. return S_OK;
  1565. }
  1566. HRESULT CDNSServerNode::SaveToStream(IStream* pStm)
  1567. {
  1568. // for each server name, write # of chars+NULL, and then the name
  1569. ULONG cbWrite = 0;
  1570. ULONG nLen = 0;
  1571. static PCWSTR pszLocalHost = L"localhost.";
  1572. if (IsLocalServer())
  1573. {
  1574. nLen = static_cast<ULONG>(wcslen(pszLocalHost) + 1);
  1575. VERIFY(SUCCEEDED(pStm->Write((void*)&nLen, sizeof(UINT),&cbWrite)));
  1576. ASSERT(cbWrite == sizeof(UINT));
  1577. VERIFY(SUCCEEDED(pStm->Write((void*)(pszLocalHost), sizeof(WCHAR)*nLen,&cbWrite)));
  1578. ASSERT(cbWrite == sizeof(WCHAR)*nLen);
  1579. }
  1580. else
  1581. {
  1582. nLen = static_cast<ULONG>(wcslen(GetDisplayName())+1); // WCHAR including NULL
  1583. VERIFY(SUCCEEDED(pStm->Write((void*)&nLen, sizeof(UINT),&cbWrite)));
  1584. ASSERT(cbWrite == sizeof(UINT));
  1585. VERIFY(SUCCEEDED(pStm->Write((void*)(GetDisplayName()), sizeof(WCHAR)*nLen,&cbWrite)));
  1586. ASSERT(cbWrite == sizeof(WCHAR)*nLen);
  1587. }
  1588. VERIFY(SUCCEEDED(m_testOptions.Save(pStm)));
  1589. return S_OK;
  1590. }
  1591. HRESULT CDNSServerNode::OnNewZone(CComponentDataObject* pComponentData, CNodeList*)
  1592. {
  1593. ASSERT(pComponentData != NULL);
  1594. ASSERT(pComponentData != NULL);
  1595. CDNSZoneWizardHolder holder(pComponentData);
  1596. holder.Initialize(this);
  1597. holder.DoModalWizard();
  1598. return S_OK;
  1599. }
  1600. void CDNSServerNode::OnUpdateDataFiles(CComponentDataObject* pComponentData)
  1601. {
  1602. // if there are sheets up, ask to close them down, because a
  1603. // failure would "Red X" the server and remove all the children
  1604. if (IsSheetLocked())
  1605. {
  1606. if (!CanCloseSheets())
  1607. return;
  1608. pComponentData->GetPropertyPageHolderTable()->DeleteSheetsOfNode(this);
  1609. }
  1610. OnChangeState(pComponentData); // move to loading
  1611. m_dwErr = WriteDirtyZones();
  1612. // if there is a failure, remove all children,
  1613. // will need a refresh to get them back
  1614. if (m_dwErr != 0)
  1615. {
  1616. RemoveAllChildrenHelper(pComponentData);
  1617. ASSERT(!HasChildren());
  1618. }
  1619. OnChangeState(pComponentData); // move to loaded or unableToLoad
  1620. }
  1621. void CDNSServerNode::OnClearCache(CComponentDataObject* pComponentData)
  1622. {
  1623. // if there is a cache folder and it is not hidden, delegate to it
  1624. if ((m_pCacheFolderNode != NULL) && ((m_pCacheFolderNode->GetFlags() & TN_FLAG_HIDDEN) == 0))
  1625. {
  1626. m_pCacheFolderNode->OnClearCache(pComponentData);
  1627. return;
  1628. }
  1629. // directly call into the server
  1630. DNS_STATUS err;
  1631. { // scope for wait cursor
  1632. CWaitCursor wait;
  1633. err = ClearCache();
  1634. }
  1635. if (err != 0)
  1636. {
  1637. // need to let the user know the operation failed
  1638. DNSErrorDialog(err, IDS_MSG_SERVER_FAIL_CLEAR_CACHE);
  1639. return;
  1640. }
  1641. if (m_pCacheFolderNode != NULL)
  1642. {
  1643. ASSERT(m_pCacheFolderNode->GetFlags() & TN_FLAG_HIDDEN);
  1644. // the cache folder is there, but hidden, so we just have
  1645. // to call the API and remove its children
  1646. m_pCacheFolderNode->RemoveAllChildrenFromList();
  1647. }
  1648. }
  1649. BOOL CDNSServerNode::HasPropertyPages(DATA_OBJECT_TYPES,
  1650. BOOL* pbHideVerb,
  1651. CNodeList* pNodeList)
  1652. {
  1653. if (pNodeList->GetCount() > 1) // multiple selection
  1654. {
  1655. return FALSE;
  1656. }
  1657. *pbHideVerb = FALSE; // always show the verb
  1658. // cannot have property pages when in loading, notLoaded, or the thread lock state
  1659. return (!IsThreadLocked() && (m_nState != notLoaded) && (m_nState != loading));
  1660. }
  1661. HRESULT CDNSServerNode::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider,
  1662. LONG_PTR handle,
  1663. CNodeList* pNodeList)
  1664. {
  1665. CWaitCursor wait;
  1666. ASSERT(pNodeList->GetCount() == 1); // multi-select not support
  1667. ASSERT(m_nState != loading);
  1668. CComponentDataObject* pComponentDataObject =
  1669. ((CRootData*)(GetContainer()->GetRootContainer()))->GetComponentDataObject();
  1670. ASSERT(pComponentDataObject != NULL);
  1671. //
  1672. // Refresh the domain forwarders node under the server so that it has current data,
  1673. // but do it manually since we have to enumerate synchronously
  1674. //
  1675. CDNSDomainForwardersNode* pDomainForwardersNode = GetDomainForwardersNode();
  1676. if (pDomainForwardersNode != NULL)
  1677. {
  1678. pDomainForwardersNode->RemoveAllChildrenHelper(pComponentDataObject);
  1679. pDomainForwardersNode->OnEnumerate(pComponentDataObject, FALSE);
  1680. }
  1681. if (m_pServInfoEx != NULL)
  1682. {
  1683. VERIFY(m_pServInfoEx->Query(GetRPCName()) == 0);
  1684. }
  1685. CDNSServerPropertyPageHolder* pHolder =
  1686. new CDNSServerPropertyPageHolder((CDNSRootData*)GetContainer(), this, pComponentDataObject);
  1687. ASSERT(pHolder != NULL);
  1688. pHolder->SetStartPageCode(m_nStartProppage);
  1689. pHolder->SetSheetTitle(IDS_PROP_SHEET_TITLE_FMT, this);
  1690. return pHolder->CreateModelessSheet(lpProvider, handle);
  1691. }
  1692. void CDNSServerNode::DecrementSheetLockCount()
  1693. {
  1694. CTreeNode::DecrementSheetLockCount();
  1695. m_nStartProppage = -1;
  1696. }
  1697. BOOL CDNSServerQueryObj::Enumerate()
  1698. {
  1699. // query the server to find out if it has a cache
  1700. BOOL bHasRootZone = FALSE;
  1701. DNS_STATUS err = ::ServerHasRootZone(m_szServerName, &bHasRootZone);
  1702. if (err != 0)
  1703. {
  1704. OnError(err);
  1705. return FALSE; // failed to get answer
  1706. }
  1707. CDNSRootHintsNode* pRootHintsNode = NULL;
  1708. // if there is not a root zone, the server is not authoritated for the root
  1709. // so create the root hints folder and ask it to query for NS and A records
  1710. if (!bHasRootZone)
  1711. {
  1712. pRootHintsNode = new CDNSRootHintsNode;
  1713. err = pRootHintsNode->QueryForRootHints(m_szServerName, m_dwServerVersion);
  1714. if (err != 0)
  1715. {
  1716. //
  1717. // NOTE: permissions are different for the Root Hints so we will
  1718. // fail this silently
  1719. //
  1720. // OnError(err);
  1721. delete pRootHintsNode;
  1722. pRootHintsNode = NULL;
  1723. // return FALSE; // failed in the query, exit without putting folders
  1724. }
  1725. }
  1726. // get server info
  1727. CDNSServerInfoEx* pServerInfoEx = new CDNSServerInfoEx;
  1728. err = pServerInfoEx->Query(m_szServerName);
  1729. if (err != 0)
  1730. {
  1731. OnError(err);
  1732. delete pServerInfoEx;
  1733. pServerInfoEx = NULL;
  1734. if (pRootHintsNode != NULL)
  1735. {
  1736. delete pRootHintsNode;
  1737. pRootHintsNode = NULL;
  1738. }
  1739. return FALSE; // stop if could not get server info
  1740. }
  1741. // all went well, finally send data
  1742. VERIFY(AddQueryResult(pServerInfoEx)); // server info data
  1743. if (!bHasRootZone)
  1744. {
  1745. ASSERT(pRootHintsNode != NULL);
  1746. VERIFY(AddQueryResult(pRootHintsNode));
  1747. }
  1748. //
  1749. // create cache data folder
  1750. //
  1751. VERIFY(AddQueryResult(new CDNSCacheNode));
  1752. //
  1753. // create the fwd/rev lookup zones folders
  1754. //
  1755. VERIFY(AddQueryResult(new CDNSForwardZonesNode));
  1756. VERIFY(AddQueryResult(new CDNSReverseZonesNode));
  1757. //
  1758. // Always add the domain forwarders folder here so that it can be enumerated immediately
  1759. //
  1760. VERIFY(AddQueryResult(new CDNSDomainForwardersNode));
  1761. return FALSE; // end thread
  1762. }
  1763. HRESULT CDNSServerNode::GetResultViewType(CComponentDataObject*,
  1764. LPOLESTR *ppViewType,
  1765. long *pViewOptions)
  1766. {
  1767. HRESULT hr = S_FALSE;
  1768. if ((!IsServerConfigured() ||
  1769. m_nState == accessDenied ||
  1770. m_nState == unableToLoad ||
  1771. !m_testResultList.LastQuerySuceeded()) &&
  1772. m_bShowMessages)
  1773. {
  1774. *pViewOptions = MMC_VIEW_OPTIONS_NOLISTVIEWS;
  1775. LPOLESTR psz = NULL;
  1776. StringFromCLSID(CLSID_MessageView, &psz);
  1777. USES_CONVERSION;
  1778. if (psz != NULL)
  1779. {
  1780. *ppViewType = psz;
  1781. hr = S_OK;
  1782. }
  1783. }
  1784. else
  1785. {
  1786. *pViewOptions = MMC_VIEW_OPTIONS_NONE;
  1787. *ppViewType = NULL;
  1788. hr = S_FALSE;
  1789. }
  1790. return hr;
  1791. }
  1792. HRESULT CDNSServerNode::OnShow(LPCONSOLE lpConsole)
  1793. {
  1794. CComPtr<IUnknown> spUnknown;
  1795. CComPtr<IMessageView> spMessageView;
  1796. HRESULT hr = lpConsole->QueryResultView(&spUnknown);
  1797. if (FAILED(hr))
  1798. return S_OK;
  1799. hr = spUnknown->QueryInterface(IID_IMessageView, (PVOID*)&spMessageView);
  1800. if (SUCCEEDED(hr))
  1801. {
  1802. CString szTitle, szMessage;
  1803. IconIdentifier iconID;
  1804. if (!IsServerConfigured())
  1805. {
  1806. VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_CONFIG_SERVER_TITLE));
  1807. VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_CONFIG_SERVER_MESSAGE));
  1808. iconID = Icon_Information;
  1809. }
  1810. else if (m_testResultList.LastQuerySuceeded())
  1811. {
  1812. if (m_nState == accessDenied)
  1813. {
  1814. VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_ACCESS_DENIED_TITLE));
  1815. VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_ACCESS_DENIED_MESSAGE));
  1816. iconID = Icon_Error;
  1817. }
  1818. else // Unable to load and other unknown errors
  1819. {
  1820. VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_NOT_LOADED_TITLE));
  1821. VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_NOT_LOADED_MESSAGE));
  1822. iconID = Icon_Error;
  1823. }
  1824. }
  1825. else
  1826. {
  1827. VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_QUERY_FAILED_TITLE));
  1828. VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_QUERY_FAILED_MESSAGE));
  1829. iconID = Icon_Error;
  1830. }
  1831. spMessageView->SetTitleText(szTitle);
  1832. spMessageView->SetBodyText(szMessage);
  1833. spMessageView->SetIcon(iconID);
  1834. }
  1835. return S_OK;
  1836. }
  1837. CQueryObj* CDNSServerNode::OnCreateQuery()
  1838. {
  1839. CDNSRootData* pRootData = (CDNSRootData*)GetRootContainer();
  1840. ASSERT(pRootData != NULL);
  1841. CDNSServerQueryObj* pQuery =
  1842. new CDNSServerQueryObj(pRootData->IsAdvancedView(), 0x0 /*version not known yet*/);
  1843. pQuery->m_szServerName = m_szDisplayName;
  1844. return pQuery;
  1845. }
  1846. BOOL CDNSServerNode::OnRefresh(CComponentDataObject* pComponentData,
  1847. CNodeList* pNodeList)
  1848. {
  1849. if (pNodeList->GetCount() > 1) // multiple selection
  1850. {
  1851. BOOL bRet = TRUE;
  1852. POSITION pos = pNodeList->GetHeadPosition();
  1853. while (pos != NULL)
  1854. {
  1855. CTreeNode* pNode = pNodeList->GetNext(pos);
  1856. ASSERT(pNode != NULL);
  1857. CNodeList nodeList;
  1858. nodeList.AddTail(pNode);
  1859. if (!pNode->OnRefresh(pComponentData, &nodeList))
  1860. {
  1861. bRet = FALSE;
  1862. }
  1863. }
  1864. return bRet;
  1865. }
  1866. //
  1867. // Single selections
  1868. //
  1869. if (CMTContainerNode::OnRefresh(pComponentData, pNodeList))
  1870. {
  1871. m_pCacheFolderNode = NULL;
  1872. m_pFwdZonesFolderNode = NULL;
  1873. m_pRevZonesFolderNode = NULL;
  1874. m_pDomainForwardersFolderNode = NULL;
  1875. FreeRootHints();
  1876. FreeServInfo();
  1877. return TRUE;
  1878. }
  1879. return FALSE;
  1880. }
  1881. void CDNSServerNode::OnHaveData(CObjBase* pObj, CComponentDataObject* pComponentDataObject)
  1882. {
  1883. // the first message coming should be server info struct, not kept in the list of children
  1884. if (IS_CLASS(*pObj, CDNSServerInfoEx))
  1885. {
  1886. AttachServerInfo(dynamic_cast<CDNSServerInfoEx*>(pObj));
  1887. return;
  1888. }
  1889. // the root hints node is special and not kept in the list of children
  1890. if (IS_CLASS(*pObj, CDNSRootHintsNode))
  1891. {
  1892. CDNSRootHintsNode* pNewRootHints = dynamic_cast<CDNSRootHintsNode*>(pObj);
  1893. if (pNewRootHints != NULL)
  1894. {
  1895. AttachRootHints(pNewRootHints);
  1896. }
  1897. ASSERT(m_pRootHintsNode != NULL);
  1898. return;
  1899. }
  1900. // set cached pointers for fdw/rev zones folders
  1901. if (IS_CLASS(*pObj, CDNSForwardZonesNode))
  1902. {
  1903. ASSERT(m_pFwdZonesFolderNode == NULL);
  1904. m_pFwdZonesFolderNode = dynamic_cast<CDNSForwardZonesNode*>(pObj);
  1905. ASSERT(m_pFwdZonesFolderNode != NULL);
  1906. }
  1907. else if (IS_CLASS(*pObj, CDNSReverseZonesNode))
  1908. {
  1909. ASSERT(m_pRevZonesFolderNode == NULL);
  1910. m_pRevZonesFolderNode = dynamic_cast<CDNSReverseZonesNode*>(pObj);
  1911. ASSERT(m_pRevZonesFolderNode != NULL);
  1912. }
  1913. else if (IS_CLASS(*pObj, CDNSCacheNode))
  1914. {
  1915. //
  1916. // the cache folder node can be shown or not, depending on the view options
  1917. //
  1918. ASSERT(m_pCacheFolderNode == NULL);
  1919. m_pCacheFolderNode = dynamic_cast<CDNSCacheNode*>(pObj);
  1920. ASSERT(m_pCacheFolderNode != NULL);
  1921. CDNSRootData* pRootData = (CDNSRootData*)pComponentDataObject->GetRootData();
  1922. if (!pRootData->IsAdvancedView())
  1923. {
  1924. m_pCacheFolderNode->SetFlagsDown(TN_FLAG_HIDDEN,TRUE); // mark it hidden, will not be added to UI
  1925. }
  1926. }
  1927. else if (IS_CLASS(*pObj, CDNSDomainForwardersNode))
  1928. {
  1929. //
  1930. // The domain forwarders node should never be shown
  1931. //
  1932. ASSERT(m_pDomainForwardersFolderNode == NULL);
  1933. m_pDomainForwardersFolderNode = dynamic_cast<CDNSDomainForwardersNode*>(pObj);
  1934. ASSERT(m_pDomainForwardersFolderNode != NULL);
  1935. //
  1936. // Make sure its hidden in the UI
  1937. //
  1938. m_pDomainForwardersFolderNode->SetFlagsDown(TN_FLAG_HIDDEN, TRUE);
  1939. }
  1940. CDNSMTContainerNode::OnHaveData(pObj,pComponentDataObject);
  1941. }
  1942. BOOL CDNSServerNode::OnAddMenuItem(LPCONTEXTMENUITEM2 pContextMenuItem2,
  1943. long*)
  1944. {
  1945. // gray out commands that need data from the server
  1946. if ((m_nState != loaded) && ( (pContextMenuItem2->lCommandID == IDM_SERVER_NEW_ZONE) ||
  1947. (pContextMenuItem2->lCommandID == IDM_SERVER_UPDATE_DATA_FILES) ||
  1948. (pContextMenuItem2->lCommandID == IDM_SERVER_CLEAR_CACHE) ||
  1949. (pContextMenuItem2->lCommandID == IDM_SERVER_SET_AGING) ||
  1950. (pContextMenuItem2->lCommandID == IDM_SERVER_SCAVENGE)
  1951. #ifdef USE_NDNC
  1952. ||(pContextMenuItem2->lCommandID == IDM_SERVER_CREATE_NDNC)
  1953. #endif
  1954. ) )
  1955. {
  1956. pContextMenuItem2->fFlags |= MF_GRAYED;
  1957. }
  1958. if ((pContextMenuItem2->lCommandID == IDM_SERVER_CONFIGURE) && IsServerConfigured())
  1959. {
  1960. return FALSE;
  1961. }
  1962. #ifdef USE_NDNC
  1963. if ((pContextMenuItem2->lCommandID == IDM_SERVER_CREATE_NDNC) &&
  1964. (m_nState != loaded ||
  1965. GetBuildNumber() < DNS_SRV_BUILD_NUMBER_WHISTLER ||
  1966. (GetMajorVersion() <= DNS_SRV_MAJOR_VERSION_NT_5 &&
  1967. GetMinorVersion() < DNS_SRV_MINOR_VERSION_WHISTLER) ||
  1968. ContainsDefaultNDNCs()))
  1969. {
  1970. return FALSE;
  1971. }
  1972. #endif
  1973. // this command might cause a refresh
  1974. if ( IsThreadLocked() && (pContextMenuItem2->lCommandID == IDM_SERVER_CLEAR_CACHE))
  1975. {
  1976. pContextMenuItem2->fFlags |= MF_GRAYED;
  1977. }
  1978. // add toggle menu item for advanced view
  1979. if (pContextMenuItem2->lCommandID == IDM_SNAPIN_ADVANCED_VIEW)
  1980. {
  1981. pContextMenuItem2->fFlags = ((CDNSRootData*)GetRootContainer())->IsAdvancedView() ? MF_CHECKED : 0;
  1982. return TRUE;
  1983. }
  1984. if (pContextMenuItem2->lCommandID == IDM_SNAPIN_FILTERING)
  1985. {
  1986. if (((CDNSRootData*)GetRootContainer())->IsFilteringEnabled())
  1987. {
  1988. pContextMenuItem2->fFlags = MF_CHECKED;
  1989. }
  1990. return TRUE;
  1991. }
  1992. if (pContextMenuItem2->lCommandID == IDM_SNAPIN_MESSAGE)
  1993. {
  1994. if (m_bShowMessages)
  1995. {
  1996. pContextMenuItem2->fFlags = MF_CHECKED;
  1997. }
  1998. }
  1999. return TRUE;
  2000. }
  2001. BOOL CDNSServerNode::OnSetDeleteVerbState(DATA_OBJECT_TYPES,
  2002. BOOL* pbHide,
  2003. CNodeList* pNodeList)
  2004. {
  2005. if (pNodeList->GetCount() > 1) // multiple selection
  2006. {
  2007. *pbHide = TRUE;
  2008. return FALSE;
  2009. }
  2010. if (((CDNSRootData*)GetRootContainer())->GetComponentDataObject()->IsExtensionSnapin())
  2011. {
  2012. // for extensions, remove the delete verb
  2013. *pbHide = TRUE;
  2014. return FALSE; // disable
  2015. }
  2016. *pbHide = FALSE;
  2017. TRACE(_T("CDNSServerNode::OnSetDeleteVerbState() IsThreadLocked() == %d\n"),
  2018. IsThreadLocked());
  2019. return !IsThreadLocked();
  2020. }
  2021. BOOL CDNSServerNode::OnSetRefreshVerbState(DATA_OBJECT_TYPES,
  2022. BOOL* pbHide,
  2023. CNodeList*)
  2024. {
  2025. *pbHide = FALSE;
  2026. return !IsThreadLocked();
  2027. }
  2028. CDNSZoneNode* CDNSServerNode::GetNewZoneNode()
  2029. {
  2030. CDNSZoneNode* pZoneNode = new CDNSZoneNode();
  2031. ASSERT(pZoneNode != NULL);
  2032. pZoneNode->SetServerNode(this);
  2033. return pZoneNode;
  2034. }
  2035. #ifdef USE_NDNC
  2036. DNS_STATUS CDNSServerNode::CreatePrimaryZone(LPCTSTR lpszName, LPCTSTR lpszFileName,
  2037. BOOL bLoadExisting,
  2038. BOOL bFwd,
  2039. BOOL bDSIntegrated,
  2040. UINT nDynamicUpdate,
  2041. CComponentDataObject* pComponentData,
  2042. ReplicationType replType,
  2043. PCWSTR pszPartitionName)
  2044. {
  2045. CDNSRootData* pRootData = (CDNSRootData*)pComponentData->GetRootData();
  2046. ASSERT(pRootData != NULL);
  2047. CDNSZoneNode* pZoneNode = GetNewZoneNode();
  2048. pZoneNode->SetNames(TRUE /* isZone*/, !bFwd, pRootData->IsAdvancedView(),
  2049. lpszName, lpszName);
  2050. DNS_STATUS err = 0;
  2051. if (bDSIntegrated && !(replType == none || replType == w2k))
  2052. {
  2053. err = pZoneNode->CreatePrimaryInDirectoryPartition(bLoadExisting,
  2054. nDynamicUpdate,
  2055. replType,
  2056. pszPartitionName);
  2057. }
  2058. else
  2059. {
  2060. err = pZoneNode->CreatePrimary(lpszFileName, bLoadExisting, bDSIntegrated, nDynamicUpdate);
  2061. }
  2062. if (err != 0)
  2063. {
  2064. // fail
  2065. delete pZoneNode;
  2066. return err;
  2067. }
  2068. // succeeded, need to add to the UI, if possible
  2069. if (IsExpanded())
  2070. {
  2071. CCathegoryFolderNode* pCathegoryFolder = GetAuthoritatedZoneFolder(bFwd);
  2072. if ( (pCathegoryFolder != NULL) && pCathegoryFolder->IsEnumerated() )
  2073. {
  2074. VERIFY(pCathegoryFolder->AddChildToListAndUI(pZoneNode, pComponentData));
  2075. pComponentData->SetDescriptionBarText(pCathegoryFolder);
  2076. }
  2077. else
  2078. {
  2079. delete pZoneNode; // the enumeration will add it
  2080. }
  2081. }
  2082. else
  2083. {
  2084. delete pZoneNode; // the expansion will get the zone from the RPC when expanding subfolders
  2085. }
  2086. return err;
  2087. }
  2088. #else
  2089. DNS_STATUS CDNSServerNode::CreatePrimaryZone(LPCTSTR lpszName, LPCTSTR lpszFileName,
  2090. BOOL bLoadExisting,
  2091. BOOL bFwd,
  2092. BOOL bDSIntegrated,
  2093. UINT nDynamicUpdate,
  2094. CComponentDataObject* pComponentData)
  2095. {
  2096. CDNSRootData* pRootData = (CDNSRootData*)pComponentData->GetRootData();
  2097. ASSERT(pRootData != NULL);
  2098. CDNSZoneNode* pZoneNode = GetNewZoneNode();
  2099. pZoneNode->SetNames(TRUE /* isZone*/, !bFwd, pRootData->IsAdvancedView(),
  2100. lpszName, lpszName);
  2101. DNS_STATUS err = pZoneNode->CreatePrimary(lpszFileName, bLoadExisting, bDSIntegrated, nDynamicUpdate);
  2102. if (err != 0)
  2103. {
  2104. // fail
  2105. delete pZoneNode;
  2106. return err;
  2107. }
  2108. // succeeded, need to add to the UI, if possible
  2109. if (IsExpanded())
  2110. {
  2111. CCathegoryFolderNode* pCathegoryFolder = GetAuthoritatedZoneFolder(bFwd);
  2112. if ( (pCathegoryFolder != NULL) && pCathegoryFolder->IsEnumerated() )
  2113. {
  2114. VERIFY(pCathegoryFolder->AddChildToListAndUI(pZoneNode, pComponentData));
  2115. pComponentData->SetDescriptionBarText(pCathegoryFolder);
  2116. }
  2117. else
  2118. {
  2119. delete pZoneNode; // the enumeration will add it
  2120. }
  2121. }
  2122. else
  2123. {
  2124. delete pZoneNode; // the expansion will get the zone from the RPC when expanding subfolders
  2125. }
  2126. return err;
  2127. }
  2128. #endif //USE_NDNC
  2129. DNS_STATUS CDNSServerNode::CreateSecondaryZone(LPCTSTR lpszName, LPCTSTR lpszFileName,
  2130. BOOL bLoadExisting, BOOL bFwd,
  2131. DWORD* ipMastersArray, int nIPMastersCount, CComponentDataObject* pComponentData)
  2132. {
  2133. CDNSRootData* pRootData = (CDNSRootData*)pComponentData->GetRootData();
  2134. ASSERT(pRootData != NULL);
  2135. CDNSZoneNode* pZoneNode = GetNewZoneNode();
  2136. pZoneNode->SetNames(TRUE /* isZone*/, !bFwd, pRootData->IsAdvancedView(),
  2137. lpszName, lpszName);
  2138. DNS_STATUS err = pZoneNode->CreateSecondary(ipMastersArray, nIPMastersCount,
  2139. lpszFileName, bLoadExisting);
  2140. if (err != 0)
  2141. {
  2142. // fail
  2143. delete pZoneNode;
  2144. return err;
  2145. }
  2146. // succeeded, need to add to the UI, if possible
  2147. if (IsExpanded())
  2148. {
  2149. CCathegoryFolderNode* pCathegoryFolder = GetAuthoritatedZoneFolder(bFwd);
  2150. if ( (pCathegoryFolder != NULL) && pCathegoryFolder->IsEnumerated() )
  2151. {
  2152. VERIFY(pCathegoryFolder->AddChildToListAndUI(pZoneNode, pComponentData));
  2153. pComponentData->SetDescriptionBarText(pCathegoryFolder);
  2154. }
  2155. else
  2156. {
  2157. delete pZoneNode; // the enumeration will add it
  2158. }
  2159. }
  2160. else
  2161. {
  2162. delete pZoneNode; // the expansion will get the zone from the RPC when expanding subfolders
  2163. }
  2164. return err;
  2165. }
  2166. #ifdef USE_NDNC
  2167. DNS_STATUS CDNSServerNode::CreateStubZone(LPCTSTR lpszName,
  2168. LPCTSTR lpszFileName,
  2169. BOOL bLoadExisting,
  2170. BOOL bDSIntegrated,
  2171. BOOL bFwd,
  2172. DWORD* ipMastersArray,
  2173. int nIPMastersCount,
  2174. BOOL bLocalListOfMasters,
  2175. CComponentDataObject* pComponentData,
  2176. ReplicationType replType,
  2177. PCWSTR pszPartitionName)
  2178. {
  2179. CDNSRootData* pRootData = (CDNSRootData*)pComponentData->GetRootData();
  2180. ASSERT(pRootData != NULL);
  2181. CDNSZoneNode* pZoneNode = GetNewZoneNode();
  2182. pZoneNode->SetNames(TRUE /* isZone*/, !bFwd, pRootData->IsAdvancedView(),
  2183. lpszName, lpszName);
  2184. USES_CONVERSION;
  2185. DNS_STATUS err = 0;
  2186. if (bDSIntegrated && !(replType == none || replType == w2k))
  2187. {
  2188. err = pZoneNode->CreateStubInDirectoryPartition(ipMastersArray,
  2189. nIPMastersCount,
  2190. bLoadExisting,
  2191. replType,
  2192. pszPartitionName);
  2193. }
  2194. else
  2195. {
  2196. err = pZoneNode->CreateStub(ipMastersArray,
  2197. nIPMastersCount,
  2198. lpszFileName,
  2199. bLoadExisting,
  2200. bDSIntegrated);
  2201. }
  2202. if (err != 0)
  2203. {
  2204. // fail
  2205. delete pZoneNode;
  2206. return err;
  2207. }
  2208. // succeeded, need to add to the UI, if possible
  2209. if (IsExpanded())
  2210. {
  2211. CCathegoryFolderNode* pCathegoryFolder = GetAuthoritatedZoneFolder(bFwd);
  2212. if ( (pCathegoryFolder != NULL) && pCathegoryFolder->IsEnumerated() )
  2213. {
  2214. VERIFY(pCathegoryFolder->AddChildToListAndUI(pZoneNode, pComponentData));
  2215. pComponentData->SetDescriptionBarText(pCathegoryFolder);
  2216. }
  2217. else
  2218. {
  2219. delete pZoneNode; // the enumeration will add it
  2220. }
  2221. }
  2222. else
  2223. {
  2224. delete pZoneNode; // the expansion will get the zone from the RPC when expanding subfolders
  2225. }
  2226. //
  2227. // Change to the local list of masters after the zone has been created
  2228. //
  2229. if (bLocalListOfMasters)
  2230. {
  2231. err = ::DnssrvResetZoneMastersEx(GetRPCName(), // Server name
  2232. W_TO_UTF8(pZoneNode->GetFullName()), // Zone name
  2233. nIPMastersCount,
  2234. ipMastersArray,
  2235. TRUE); // LocalListOfMasters
  2236. if (err != 0)
  2237. return err;
  2238. }
  2239. else
  2240. {
  2241. /*
  2242. err = ::DnssrvResetZoneMastersEx(GetRPCName(), // Server name
  2243. W_TO_UTF8(pZoneNode->GetFullName()), // Zone name
  2244. 0,
  2245. NULL,
  2246. TRUE); // LocalListOfMasters
  2247. if (err != 0)
  2248. return err;
  2249. */
  2250. }
  2251. return err;
  2252. }
  2253. #else
  2254. DNS_STATUS CDNSServerNode::CreateStubZone(LPCTSTR lpszName,
  2255. LPCTSTR lpszFileName,
  2256. BOOL bLoadExisting,
  2257. BOOL bDSIntegrated,
  2258. BOOL bFwd,
  2259. DWORD* ipMastersArray,
  2260. int nIPMastersCount,
  2261. BOOL bLocalListOfMasters,
  2262. CComponentDataObject* pComponentData)
  2263. {
  2264. CDNSRootData* pRootData = (CDNSRootData*)pComponentData->GetRootData();
  2265. ASSERT(pRootData != NULL);
  2266. CDNSZoneNode* pZoneNode = GetNewZoneNode();
  2267. pZoneNode->SetNames(TRUE /* isZone*/, !bFwd, pRootData->IsAdvancedView(),
  2268. lpszName, lpszName);
  2269. USES_CONVERSION;
  2270. DNS_STATUS err = pZoneNode->CreateStub(ipMastersArray,
  2271. nIPMastersCount,
  2272. lpszFileName,
  2273. bLoadExisting,
  2274. bDSIntegrated);
  2275. if (err != 0)
  2276. {
  2277. // fail
  2278. delete pZoneNode;
  2279. return err;
  2280. }
  2281. // succeeded, need to add to the UI, if possible
  2282. if (IsExpanded())
  2283. {
  2284. CCathegoryFolderNode* pCathegoryFolder = GetAuthoritatedZoneFolder(bFwd);
  2285. if ( (pCathegoryFolder != NULL) && pCathegoryFolder->IsEnumerated() )
  2286. {
  2287. VERIFY(pCathegoryFolder->AddChildToListAndUI(pZoneNode, pComponentData));
  2288. pComponentData->SetDescriptionBarText(pCathegoryFolder);
  2289. }
  2290. else
  2291. {
  2292. delete pZoneNode; // the enumeration will add it
  2293. }
  2294. }
  2295. else
  2296. {
  2297. delete pZoneNode; // the expansion will get the zone from the RPC when expanding subfolders
  2298. }
  2299. //
  2300. // Change to the local list of masters after the zone has been created
  2301. //
  2302. if (bLocalListOfMasters)
  2303. {
  2304. err = ::DnssrvResetZoneMastersEx(GetRPCName(), // Server name
  2305. W_TO_UTF8(pZoneNode->GetFullName()), // Zone name
  2306. nIPMastersCount,
  2307. ipMastersArray,
  2308. TRUE); // LocalListOfMasters
  2309. if (err != 0)
  2310. return err;
  2311. }
  2312. else
  2313. {
  2314. /*
  2315. err = ::DnssrvResetZoneMastersEx(GetRPCName(), // Server name
  2316. W_TO_UTF8(pZoneNode->GetFullName()), // Zone name
  2317. 0,
  2318. NULL,
  2319. TRUE); // LocalListOfMasters
  2320. if (err != 0)
  2321. return err;
  2322. */
  2323. }
  2324. return err;
  2325. }
  2326. #endif // USE_NDNC
  2327. DNS_STATUS CDNSServerNode::CreateForwarderZone(LPCTSTR lpszName,
  2328. DWORD* ipMastersArray,
  2329. int nIPMastersCount,
  2330. DWORD dwTimeout,
  2331. DWORD fSlave,
  2332. CComponentDataObject* pComponentData)
  2333. {
  2334. CDNSRootData* pRootData = (CDNSRootData*)pComponentData->GetRootData();
  2335. ASSERT(pRootData != NULL);
  2336. CDNSZoneNode* pZoneNode = GetNewZoneNode();
  2337. pZoneNode->SetNames(TRUE /* isZone*/,
  2338. TRUE,
  2339. pRootData->IsAdvancedView(),
  2340. lpszName,
  2341. lpszName);
  2342. DNS_STATUS err = pZoneNode->CreateForwarder(ipMastersArray,
  2343. nIPMastersCount,
  2344. dwTimeout,
  2345. fSlave);
  2346. if (err != 0)
  2347. {
  2348. //
  2349. // fail
  2350. //
  2351. delete pZoneNode;
  2352. return err;
  2353. }
  2354. //
  2355. // succeeded, need to add to the UI, if possible
  2356. //
  2357. if (IsExpanded())
  2358. {
  2359. CCathegoryFolderNode* pCathegoryFolder = GetDomainForwardersNode();
  2360. if ( (pCathegoryFolder != NULL) && pCathegoryFolder->IsEnumerated() )
  2361. {
  2362. VERIFY(pCathegoryFolder->AddChildToListAndUI(pZoneNode, pComponentData));
  2363. pComponentData->SetDescriptionBarText(pCathegoryFolder);
  2364. }
  2365. else
  2366. {
  2367. delete pZoneNode; // the enumeration will add it
  2368. }
  2369. }
  2370. else
  2371. {
  2372. delete pZoneNode; // the expansion will get the zone from the RPC when expanding subfolders
  2373. }
  2374. return err;
  2375. }
  2376. DNS_STATUS CDNSServerNode::WriteDirtyZones()
  2377. {
  2378. USES_CONVERSION;
  2379. return ::DnssrvWriteDirtyZones(GetServerNode()->GetRPCName());
  2380. }
  2381. BOOL CDNSServerNode::CanUseADS()
  2382. {
  2383. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2384. if (GetMajorVersion() <= DNS_SRV_MAJOR_VERSION_NT_4)
  2385. return FALSE;
  2386. return m_pServInfoEx->m_pServInfo->fDsAvailable;
  2387. }
  2388. DWORD CDNSServerNode::GetVersion()
  2389. {
  2390. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2391. if (m_pServInfoEx->m_pServInfo != NULL)
  2392. {
  2393. return m_pServInfoEx->m_pServInfo->dwVersion;
  2394. }
  2395. return (DWORD)-1;
  2396. }
  2397. void _CopyStringAndFree(CString& sz, LPWSTR lpsz)
  2398. {
  2399. sz = lpsz;
  2400. if (lpsz)
  2401. ::DnssrvFreeRpcBuffer((PDNS_RPC_BUFFER)lpsz);
  2402. }
  2403. void _LdapPathFromX500(CString& szLdap, PDNS_RPC_SERVER_INFO pInfo, LPCWSTR lpszX500Name)
  2404. {
  2405. ASSERT(pInfo != NULL);
  2406. ASSERT(pInfo->pszServerName != NULL);
  2407. USES_CONVERSION;
  2408. LPCWSTR lpszServerName = UTF8_TO_W(pInfo->pszServerName);
  2409. szLdap.Format(L"LDAP://%s/%s", lpszServerName, lpszX500Name);
  2410. }
  2411. void CDNSServerNode::CreateDsServerLdapPath(CString& sz)
  2412. {
  2413. ASSERT(m_pServInfoEx != NULL);
  2414. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2415. if (m_pServInfoEx->m_pServInfo != NULL)
  2416. {
  2417. CString szX500;
  2418. _CopyStringAndFree(szX500,::DnssrvCreateDsServerName(m_pServInfoEx->m_pServInfo));
  2419. CreateLdapPathFromX500Name(szX500, sz);
  2420. }
  2421. else
  2422. sz.Empty();
  2423. }
  2424. void CDNSServerNode::CreateDsZoneLdapPath(CDNSZoneNode* pZoneNode, CString& sz)
  2425. {
  2426. PCWSTR pszDN = pZoneNode->GetDN();
  2427. if (!pszDN)
  2428. {
  2429. ASSERT(m_pServInfoEx != NULL);
  2430. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2431. if (m_pServInfoEx->m_pServInfo != NULL)
  2432. {
  2433. CString szX500;
  2434. _CopyStringAndFree(szX500, ::DnssrvCreateDsZoneName(m_pServInfoEx->m_pServInfo,
  2435. (LPWSTR)pZoneNode->GetFullName()));
  2436. CreateLdapPathFromX500Name( szX500, sz);
  2437. }
  2438. else
  2439. {
  2440. sz.Empty();
  2441. }
  2442. }
  2443. else
  2444. {
  2445. CreateLdapPathFromX500Name(pszDN, sz);
  2446. }
  2447. }
  2448. void CDNSServerNode::CreateDsZoneName(CDNSZoneNode* pZoneNode, CString& sz)
  2449. {
  2450. ASSERT(m_pServInfoEx != NULL);
  2451. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2452. if (m_pServInfoEx->m_pServInfo != NULL)
  2453. {
  2454. _CopyStringAndFree(sz, ::DnssrvCreateDsZoneName(m_pServInfoEx->m_pServInfo,
  2455. (LPWSTR)pZoneNode->GetFullName()));
  2456. }
  2457. else
  2458. sz.Empty();
  2459. }
  2460. void CDNSServerNode::CreateDsNodeLdapPath(CDNSZoneNode* pZoneNode, CDNSDomainNode* pDomainNode, CString& sz)
  2461. {
  2462. ASSERT(m_pServInfoEx != NULL);
  2463. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2464. if (m_pServInfoEx->m_pServInfo != NULL)
  2465. {
  2466. // need to get the relative path of the node wrt the zone
  2467. size_t nZoneLen = wcslen(pZoneNode->GetFullName());
  2468. size_t nDomainLen = wcslen(pDomainNode->GetFullName());
  2469. size_t nRelativeNameLen = nDomainLen - nZoneLen - 1; // remove a dot
  2470. CString szRelativeName(pDomainNode->GetFullName(), static_cast<int>(nRelativeNameLen));
  2471. CString szX500;
  2472. _CopyStringAndFree(szX500, ::DnssrvCreateDsNodeName(m_pServInfoEx->m_pServInfo,
  2473. (LPWSTR)pZoneNode->GetFullName(),
  2474. (LPWSTR)(LPCWSTR)szRelativeName));
  2475. CreateLdapPathFromX500Name(szX500, sz);
  2476. }
  2477. else
  2478. sz.Empty();
  2479. }
  2480. void CDNSServerNode::CreateLdapPathFromX500Name(LPCWSTR lpszX500Name, CString& szLdapPath)
  2481. {
  2482. ASSERT(m_pServInfoEx != NULL);
  2483. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2484. if (m_pServInfoEx->m_pServInfo != NULL)
  2485. {
  2486. _LdapPathFromX500(szLdapPath, m_pServInfoEx->m_pServInfo, lpszX500Name);
  2487. }
  2488. else
  2489. szLdapPath.Empty();
  2490. }
  2491. BOOL CDNSServerNode::DoesRecursion()
  2492. {
  2493. if (m_pServInfoEx == NULL || m_pServInfoEx->m_pServInfo == NULL)
  2494. {
  2495. ASSERT(FALSE);
  2496. return TRUE;
  2497. }
  2498. return !m_pServInfoEx->m_pServInfo->fNoRecursion;
  2499. }
  2500. void CDNSServerNode::GetAdvancedOptions(BOOL* bOptionsArray)
  2501. {
  2502. ASSERT(m_pServInfoEx != NULL);
  2503. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2504. bOptionsArray[SERVER_REGKEY_ARR_INDEX_NO_RECURSION] = m_pServInfoEx->m_pServInfo->fNoRecursion;
  2505. bOptionsArray[SERVER_REGKEY_ARR_INDEX_BIND_SECONDARIES] = m_pServInfoEx->m_pServInfo->fBindSecondaries;
  2506. bOptionsArray[SERVER_REGKEY_ARR_INDEX_STRICT_FILE_PARSING] = m_pServInfoEx->m_pServInfo->fStrictFileParsing;
  2507. bOptionsArray[SERVER_REGKEY_ARR_INDEX_ROUND_ROBIN] = m_pServInfoEx->m_pServInfo->fRoundRobin;
  2508. bOptionsArray[SERVER_REGKEY_ARR_LOCAL_NET_PRIORITY] = m_pServInfoEx->m_pServInfo->fLocalNetPriority;
  2509. bOptionsArray[SERVER_REGKEY_ARR_CACHE_POLLUTION] = m_pServInfoEx->m_pServInfo->fSecureResponses;
  2510. }
  2511. DNS_STATUS CDNSServerNode::ResetAdvancedOptions(BOOL* bOptionsArray, DNS_STATUS* dwRegKeyOptionsErrorArr)
  2512. {
  2513. ASSERT(m_pServInfoEx != NULL);
  2514. DNS_STATUS err = 0;
  2515. BOOL bChanged = FALSE;
  2516. ZeroMemory(dwRegKeyOptionsErrorArr, sizeof(DNS_STATUS )*SERVER_REGKEY_ARR_SIZE);
  2517. for (UINT iKey=0; iKey < SERVER_REGKEY_ARR_SIZE; iKey++)
  2518. {
  2519. BOOL bDirty = FALSE;
  2520. switch (iKey)
  2521. {
  2522. case SERVER_REGKEY_ARR_INDEX_NO_RECURSION:
  2523. bDirty = (bOptionsArray[iKey] != m_pServInfoEx->m_pServInfo->fNoRecursion);
  2524. break;
  2525. case SERVER_REGKEY_ARR_INDEX_BIND_SECONDARIES:
  2526. bDirty = (bOptionsArray[iKey] != m_pServInfoEx->m_pServInfo->fBindSecondaries);
  2527. break;
  2528. case SERVER_REGKEY_ARR_INDEX_STRICT_FILE_PARSING:
  2529. bDirty = (bOptionsArray[iKey] != m_pServInfoEx->m_pServInfo->fStrictFileParsing);
  2530. break;
  2531. case SERVER_REGKEY_ARR_INDEX_ROUND_ROBIN:
  2532. bDirty = (bOptionsArray[iKey] != m_pServInfoEx->m_pServInfo->fRoundRobin);
  2533. break;
  2534. case SERVER_REGKEY_ARR_LOCAL_NET_PRIORITY:
  2535. bDirty = (bOptionsArray[iKey] != m_pServInfoEx->m_pServInfo->fLocalNetPriority);
  2536. break;
  2537. case SERVER_REGKEY_ARR_CACHE_POLLUTION:
  2538. bDirty = (bOptionsArray[iKey] != m_pServInfoEx->m_pServInfo->fSecureResponses);
  2539. break;
  2540. default:
  2541. ASSERT(FALSE);
  2542. }
  2543. if (bDirty)
  2544. {
  2545. dwRegKeyOptionsErrorArr[iKey] = ::DnssrvResetDwordProperty(
  2546. GetServerNode()->GetRPCName(), // server name
  2547. NULL,
  2548. _DnsServerRegkeyStringArr[iKey],
  2549. bOptionsArray[iKey]);
  2550. if (dwRegKeyOptionsErrorArr[iKey] == 0)
  2551. bChanged = TRUE;
  2552. }
  2553. }
  2554. if (bChanged)
  2555. err = GetServInfo(); // update the info
  2556. return err;
  2557. }
  2558. UCHAR CDNSServerNode::GetBootMethod()
  2559. {
  2560. ASSERT(m_pServInfoEx != NULL);
  2561. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2562. return m_pServInfoEx->m_pServInfo->fBootMethod;
  2563. }
  2564. DNS_STATUS CDNSServerNode::ResetBootMethod(UCHAR fBootMethod)
  2565. {
  2566. ASSERT(m_pServInfoEx != NULL);
  2567. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2568. DWORD err = 0;
  2569. if(fBootMethod != m_pServInfoEx->m_pServInfo->fBootMethod)
  2570. {
  2571. err = ::DnssrvResetDwordProperty(GetServerNode()->GetRPCName(), // server name
  2572. NULL,
  2573. DNS_REGKEY_BOOT_METHOD,
  2574. fBootMethod);
  2575. if (err != 0)
  2576. return err;
  2577. // all fine, update the info
  2578. err = GetServInfo();
  2579. }
  2580. return err;
  2581. }
  2582. BOOL CDNSServerNode::ContainsDefaultNDNCs()
  2583. {
  2584. //
  2585. // Enumerate the available directory partitions
  2586. //
  2587. BOOL result = FALSE;
  2588. PDNS_RPC_DP_LIST pDirectoryPartitions = NULL;
  2589. DWORD dwErr = ::DnssrvEnumDirectoryPartitions(GetRPCName(),
  2590. DNS_DP_ENLISTED,
  2591. &pDirectoryPartitions);
  2592. //
  2593. // Don't show an error if we are not able to get the available directory partitions
  2594. // We can still continue on and the user can type in the directory partition they need
  2595. //
  2596. if (dwErr == 0 && pDirectoryPartitions)
  2597. {
  2598. for (DWORD dwIdx = 0; dwIdx < pDirectoryPartitions->dwDpCount; dwIdx++)
  2599. {
  2600. PDNS_RPC_DP_INFO pDirectoryPartition = 0;
  2601. dwErr = ::DnssrvDirectoryPartitionInfo(GetRPCName(),
  2602. pDirectoryPartitions->DpArray[dwIdx]->pszDpFqdn,
  2603. &pDirectoryPartition);
  2604. if (dwErr == 0 &&
  2605. pDirectoryPartition)
  2606. {
  2607. //
  2608. // Check to see if it was an autocreated partition
  2609. //
  2610. if (pDirectoryPartition->dwFlags & DNS_DP_AUTOCREATED)
  2611. {
  2612. result = TRUE;
  2613. ::DnssrvFreeDirectoryPartitionInfo(pDirectoryPartition);
  2614. break;
  2615. }
  2616. ::DnssrvFreeDirectoryPartitionInfo(pDirectoryPartition);
  2617. }
  2618. }
  2619. ::DnssrvFreeDirectoryPartitionList(pDirectoryPartitions);
  2620. }
  2621. return result;
  2622. }
  2623. BOOL CDNSServerNode::IsServerConfigured()
  2624. {
  2625. ASSERT(m_pServInfoEx != NULL);
  2626. if (m_pServInfoEx != NULL && m_pServInfoEx->m_pServInfo != NULL)
  2627. {
  2628. return m_pServInfoEx->m_pServInfo->fAdminConfigured;
  2629. }
  2630. return TRUE;
  2631. }
  2632. DNS_STATUS CDNSServerNode::SetServerConfigured()
  2633. {
  2634. ASSERT(m_pServInfoEx != NULL);
  2635. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2636. DWORD err = 0;
  2637. if (TRUE != m_pServInfoEx->m_pServInfo->fAdminConfigured)
  2638. {
  2639. err = ::DnssrvResetDwordProperty(GetRPCName(),
  2640. NULL,
  2641. DNS_REGKEY_ADMIN_CONFIGURED,
  2642. TRUE);
  2643. if (err != 0)
  2644. return err;
  2645. err = GetServInfo();
  2646. }
  2647. return err;
  2648. }
  2649. BOOL CDNSServerNode::GetScavengingState()
  2650. {
  2651. ASSERT(m_pServInfoEx != NULL);
  2652. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2653. return m_pServInfoEx->m_pServInfo->dwScavengingInterval > 0;
  2654. }
  2655. DWORD CDNSServerNode::GetScavengingInterval()
  2656. {
  2657. ASSERT(m_pServInfoEx != NULL);
  2658. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2659. return m_pServInfoEx->m_pServInfo->dwScavengingInterval;
  2660. }
  2661. DNS_STATUS CDNSServerNode::ResetScavengingInterval(DWORD dwScavengingInterval)
  2662. {
  2663. ASSERT(m_pServInfoEx != NULL);
  2664. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2665. DWORD err = 0;
  2666. if (dwScavengingInterval != m_pServInfoEx->m_pServInfo->dwScavengingInterval)
  2667. {
  2668. DNS_RPC_NAME_AND_PARAM param;
  2669. param.dwParam = dwScavengingInterval;
  2670. param.pszNodeName = DNS_REGKEY_SCAVENGING_INTERVAL;
  2671. err = ::DnssrvOperation(
  2672. GetRPCName(),
  2673. NULL,
  2674. DNSSRV_OP_RESET_DWORD_PROPERTY,
  2675. DNSSRV_TYPEID_NAME_AND_PARAM,
  2676. & param
  2677. );
  2678. if (err != 0)
  2679. return err;
  2680. err = GetServInfo();
  2681. }
  2682. return err;
  2683. }
  2684. DWORD CDNSServerNode::GetDefaultRefreshInterval()
  2685. {
  2686. ASSERT(m_pServInfoEx != NULL);
  2687. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2688. return m_pServInfoEx->m_pServInfo->dwDefaultRefreshInterval;
  2689. }
  2690. DNS_STATUS CDNSServerNode::ResetDefaultRefreshInterval(DWORD dwRefreshInterval)
  2691. {
  2692. ASSERT(m_pServInfoEx != NULL);
  2693. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2694. DWORD err = 0;
  2695. if (dwRefreshInterval != m_pServInfoEx->m_pServInfo->dwDefaultRefreshInterval)
  2696. {
  2697. DNS_RPC_NAME_AND_PARAM param;
  2698. param.dwParam = dwRefreshInterval;
  2699. param.pszNodeName = DNS_REGKEY_DEFAULT_REFRESH_INTERVAL;
  2700. err = ::DnssrvOperation(
  2701. GetRPCName(),
  2702. NULL,
  2703. DNSSRV_OP_RESET_DWORD_PROPERTY,
  2704. DNSSRV_TYPEID_NAME_AND_PARAM,
  2705. & param
  2706. );
  2707. if (err != 0)
  2708. return err;
  2709. err = GetServInfo();
  2710. }
  2711. return err;
  2712. }
  2713. DWORD CDNSServerNode::GetDefaultNoRefreshInterval()
  2714. {
  2715. ASSERT(m_pServInfoEx != NULL);
  2716. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2717. return m_pServInfoEx->m_pServInfo->dwDefaultNoRefreshInterval;
  2718. }
  2719. DNS_STATUS CDNSServerNode::ResetDefaultNoRefreshInterval(DWORD dwNoRefreshInterval)
  2720. {
  2721. ASSERT(m_pServInfoEx != NULL);
  2722. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2723. DWORD err = 0;
  2724. if (dwNoRefreshInterval != m_pServInfoEx->m_pServInfo->dwDefaultNoRefreshInterval)
  2725. {
  2726. DNS_RPC_NAME_AND_PARAM param;
  2727. param.dwParam = dwNoRefreshInterval;
  2728. param.pszNodeName = DNS_REGKEY_DEFAULT_NOREFRESH_INTERVAL;
  2729. err = ::DnssrvOperation(
  2730. GetRPCName(),
  2731. NULL,
  2732. DNSSRV_OP_RESET_DWORD_PROPERTY,
  2733. DNSSRV_TYPEID_NAME_AND_PARAM,
  2734. & param
  2735. );
  2736. if (err != 0)
  2737. return err;
  2738. err = GetServInfo();
  2739. }
  2740. return err;
  2741. }
  2742. #ifdef USE_NDNC
  2743. PCSTR CDNSServerNode::GetDomainName()
  2744. {
  2745. ASSERT(m_pServInfoEx != NULL);
  2746. ASSERT(m_pServInfoEx->m_pServInfo);
  2747. return m_pServInfoEx->m_pServInfo->pszDomainName;
  2748. }
  2749. PCSTR CDNSServerNode::GetForestName()
  2750. {
  2751. ASSERT(m_pServInfoEx != NULL);
  2752. ASSERT(m_pServInfoEx->m_pServInfo);
  2753. return m_pServInfoEx->m_pServInfo->pszForestName;
  2754. }
  2755. #endif
  2756. DWORD CDNSServerNode::GetDefaultScavengingState()
  2757. {
  2758. ASSERT(m_pServInfoEx != NULL);
  2759. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2760. return m_pServInfoEx->m_pServInfo->fDefaultAgingState;
  2761. }
  2762. DNS_STATUS CDNSServerNode::ResetDefaultScavengingState(DWORD dwScavengingState)
  2763. {
  2764. ASSERT(m_pServInfoEx != NULL);
  2765. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2766. DWORD err = 0;
  2767. if (dwScavengingState != m_pServInfoEx->m_pServInfo->fDefaultAgingState)
  2768. {
  2769. DNS_RPC_NAME_AND_PARAM param;
  2770. param.dwParam = dwScavengingState;
  2771. param.pszNodeName = DNS_REGKEY_DEFAULT_AGING_STATE;
  2772. err = ::DnssrvOperation(
  2773. GetRPCName(),
  2774. NULL,
  2775. DNSSRV_OP_RESET_DWORD_PROPERTY,
  2776. DNSSRV_TYPEID_NAME_AND_PARAM,
  2777. & param
  2778. );
  2779. if (err != 0)
  2780. return err;
  2781. err = GetServInfo();
  2782. }
  2783. return err;
  2784. }
  2785. DWORD CDNSServerNode::GetNameCheckFlag()
  2786. {
  2787. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2788. return m_pServInfoEx->m_pServInfo->dwNameCheckFlag;
  2789. }
  2790. DNS_STATUS CDNSServerNode::ResetNameCheckFlag(DWORD dwNameCheckFlag)
  2791. {
  2792. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2793. DNS_STATUS err = 0;
  2794. // call only if the info is dirty
  2795. if (m_pServInfoEx->m_pServInfo->dwNameCheckFlag != dwNameCheckFlag)
  2796. {
  2797. USES_CONVERSION;
  2798. err = ::DnssrvResetDwordProperty(GetServerNode()->GetRPCName(), // server name
  2799. NULL,
  2800. DNS_REGKEY_NAME_CHECK_FLAG,
  2801. dwNameCheckFlag);
  2802. if (err != 0)
  2803. return err;
  2804. err = GetServInfo(); // update the info
  2805. }
  2806. return err;
  2807. }
  2808. PIP_ARRAY CDNSServerNode::GetDebugLogFilterList()
  2809. {
  2810. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2811. return m_pServInfoEx->m_pServInfo->aipLogFilter;
  2812. }
  2813. DNS_STATUS CDNSServerNode::ResetDebugLogFilterList(PIP_ARRAY pIPArray)
  2814. {
  2815. DNS_STATUS err = 0;
  2816. err = ::DnssrvResetIPListProperty(GetServerNode()->GetRPCName(), // server name
  2817. NULL,
  2818. DNS_REGKEY_LOG_IP_FILTER_LIST,
  2819. pIPArray,
  2820. 0); // dwFlags
  2821. if (err != 0)
  2822. return err;
  2823. err = GetServInfo(); // update the info
  2824. return err;
  2825. }
  2826. PCWSTR CDNSServerNode::GetDebugLogFileName()
  2827. {
  2828. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2829. return m_pServInfoEx->m_pServInfo->pwszLogFilePath;
  2830. }
  2831. DNS_STATUS CDNSServerNode::ResetDebugLogFileName(PCWSTR pszLogFileName)
  2832. {
  2833. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2834. DNS_STATUS err = 0;
  2835. if (m_pServInfoEx->m_pServInfo->pwszLogFilePath == NULL ||
  2836. _wcsicmp(m_pServInfoEx->m_pServInfo->pwszLogFilePath, pszLogFileName) != 0)
  2837. {
  2838. err = ::DnssrvResetStringProperty(GetServerNode()->GetRPCName(), // server name
  2839. NULL,
  2840. DNS_REGKEY_LOG_FILE_PATH,
  2841. pszLogFileName,
  2842. 0); // dwFlags
  2843. if (err != 0)
  2844. return err;
  2845. err = GetServInfo(); // update the info
  2846. }
  2847. return err;
  2848. }
  2849. DWORD CDNSServerNode::GetDebugLogFileMaxSize()
  2850. {
  2851. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2852. return m_pServInfoEx->m_pServInfo->dwLogFileMaxSize;
  2853. }
  2854. DNS_STATUS CDNSServerNode::ResetDebugLogFileMaxSize(DWORD dwMaxSize)
  2855. {
  2856. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2857. DNS_STATUS err = 0;
  2858. if (m_pServInfoEx->m_pServInfo->dwLogFileMaxSize != dwMaxSize)
  2859. {
  2860. err = ::DnssrvResetDwordProperty(GetServerNode()->GetRPCName(), // server name
  2861. NULL,
  2862. DNS_REGKEY_LOG_FILE_MAX_SIZE,
  2863. dwMaxSize);
  2864. if (err != 0)
  2865. return err;
  2866. err = GetServInfo(); // update the info
  2867. }
  2868. return err;
  2869. }
  2870. DWORD CDNSServerNode::GetLogLevelFlag()
  2871. {
  2872. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2873. return m_pServInfoEx->m_pServInfo->dwLogLevel;
  2874. }
  2875. DNS_STATUS CDNSServerNode::ResetLogLevelFlag(DWORD dwLogLevel)
  2876. {
  2877. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2878. DNS_STATUS err = 0;
  2879. // call only if the info is dirty
  2880. if (m_pServInfoEx->m_pServInfo->dwLogLevel != dwLogLevel)
  2881. {
  2882. USES_CONVERSION;
  2883. err = ::DnssrvResetDwordProperty(GetServerNode()->GetRPCName(), // server name
  2884. NULL,
  2885. DNS_REGKEY_LOG_LEVEL,
  2886. dwLogLevel);
  2887. if (err != 0)
  2888. return err;
  2889. err = GetServInfo(); // update the info
  2890. }
  2891. return err;
  2892. }
  2893. DWORD CDNSServerNode::GetEventLogLevelFlag()
  2894. {
  2895. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2896. return m_pServInfoEx->m_pServInfo->dwEventLogLevel;
  2897. }
  2898. DNS_STATUS CDNSServerNode::ResetEventLogLevelFlag(DWORD dwEventLogLevel)
  2899. {
  2900. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2901. DNS_STATUS err = 0;
  2902. if (m_pServInfoEx->m_pServInfo->dwEventLogLevel != dwEventLogLevel)
  2903. {
  2904. USES_CONVERSION;
  2905. err = ::DnssrvResetDwordProperty(GetServerNode()->GetRPCName(), // server name
  2906. NULL,
  2907. DNS_REGKEY_EVENTLOG_LEVEL,
  2908. dwEventLogLevel);
  2909. if (err != 0)
  2910. return err;
  2911. err = GetServInfo(); // update the info
  2912. }
  2913. return err;
  2914. }
  2915. DNS_STATUS CDNSServerNode::ResetListenAddresses(DWORD cAddrCount, PIP_ADDRESS pipAddrs)
  2916. {
  2917. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2918. USES_CONVERSION;
  2919. // make the call only if the data is dirty
  2920. DNS_STATUS err = 0;
  2921. if (!(m_pServInfoEx->m_pServInfo->aipListenAddrs == NULL && cAddrCount == 0) && // if still no addresses, skip
  2922. ((m_pServInfoEx->m_pServInfo->aipListenAddrs == NULL && cAddrCount > 0) || // no addr --> more than one
  2923. (m_pServInfoEx->m_pServInfo->aipListenAddrs->AddrCount != cAddrCount) || // change the # of addresses
  2924. (memcmp(pipAddrs, m_pServInfoEx->m_pServInfo->aipListenAddrs->AddrArray, sizeof(IP_ADDRESS)*cAddrCount) != 0)
  2925. )
  2926. )
  2927. {
  2928. IP_ADDRESS dummy;
  2929. if (pipAddrs == NULL)
  2930. {
  2931. ASSERT(cAddrCount == 0);
  2932. pipAddrs = &dummy; // RPC wants non null ip array
  2933. }
  2934. err = ::DnssrvResetServerListenAddresses(GetRPCName(), cAddrCount, pipAddrs);
  2935. }
  2936. if (err != 0)
  2937. return err;
  2938. return GetServInfo(); // update the info
  2939. }
  2940. void CDNSServerNode::GetListenAddressesInfo(DWORD* pcAddrCount, PIP_ADDRESS* ppipAddrs)
  2941. {
  2942. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2943. ASSERT(pcAddrCount != NULL);
  2944. ASSERT(ppipAddrs != NULL);
  2945. // return pointers to struct fields, caller has to copy data elsewhere
  2946. if (m_pServInfoEx->m_pServInfo->aipListenAddrs == NULL)
  2947. {
  2948. *pcAddrCount = 0;
  2949. *ppipAddrs = NULL;
  2950. }
  2951. else
  2952. {
  2953. *pcAddrCount = m_pServInfoEx->m_pServInfo->aipListenAddrs->AddrCount;
  2954. *ppipAddrs = m_pServInfoEx->m_pServInfo->aipListenAddrs->AddrArray;
  2955. }
  2956. }
  2957. void CDNSServerNode::GetServerAddressesInfo(DWORD* pcAddrCount, PIP_ADDRESS* ppipAddrs)
  2958. {
  2959. //
  2960. // Validate parameters
  2961. //
  2962. ASSERT(pcAddrCount != NULL);
  2963. ASSERT(ppipAddrs != NULL);
  2964. if (pcAddrCount == NULL ||
  2965. ppipAddrs == NULL)
  2966. {
  2967. return;
  2968. }
  2969. if (!m_pServInfoEx->HasData())
  2970. {
  2971. DNS_STATUS err = GetServInfo();
  2972. if (err != 0)
  2973. {
  2974. *pcAddrCount = 0;
  2975. *ppipAddrs = NULL;
  2976. return;
  2977. }
  2978. }
  2979. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2980. // return pointers to struct fields, caller has to copy data elsewhere
  2981. if (m_pServInfoEx->m_pServInfo->aipServerAddrs == NULL)
  2982. {
  2983. *pcAddrCount = 0;
  2984. *ppipAddrs = NULL;
  2985. }
  2986. else
  2987. {
  2988. *pcAddrCount = m_pServInfoEx->m_pServInfo->aipServerAddrs->AddrCount;
  2989. *ppipAddrs = m_pServInfoEx->m_pServInfo->aipServerAddrs->AddrArray;
  2990. }
  2991. }
  2992. DNS_STATUS CDNSServerNode::ResetForwarders(DWORD cForwardersCount, PIP_ADDRESS aipForwarders,
  2993. DWORD dwForwardTimeout, DWORD fSlave)
  2994. {
  2995. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  2996. // make the call only if the data is dirty
  2997. DNS_STATUS err = 0;
  2998. if (m_pServInfoEx->m_pServInfo->aipForwarders == NULL && cForwardersCount == 0)
  2999. return err; // there are no addresses
  3000. BOOL bDirty = (m_pServInfoEx->m_pServInfo->fSlave != fSlave) || (m_pServInfoEx->m_pServInfo->dwForwardTimeout != dwForwardTimeout) ||
  3001. (m_pServInfoEx->m_pServInfo->aipForwarders == NULL && cForwardersCount > 0) || // no addr --> more than one
  3002. (m_pServInfoEx->m_pServInfo->aipForwarders != NULL && cForwardersCount == 0) || // some addr --> no addr
  3003. (m_pServInfoEx->m_pServInfo->aipForwarders->AddrCount != cForwardersCount) || // change the # of addresses
  3004. (memcmp(aipForwarders, m_pServInfoEx->m_pServInfo->aipForwarders->AddrArray, sizeof(IP_ADDRESS)*cForwardersCount) != 0);
  3005. if (bDirty)
  3006. {
  3007. IP_ADDRESS dummy;
  3008. if (aipForwarders == NULL)
  3009. {
  3010. ASSERT(cForwardersCount == 0);
  3011. aipForwarders = &dummy; // RPC wants non null ip array
  3012. }
  3013. USES_CONVERSION;
  3014. err = ::DnssrvResetForwarders(GetRPCName(),
  3015. cForwardersCount, aipForwarders, dwForwardTimeout, fSlave);
  3016. if (err == 0)
  3017. err = GetServInfo(); // update the info
  3018. }
  3019. return err;
  3020. }
  3021. void CDNSServerNode::GetForwardersInfo(DWORD* pcForwardersCount, PIP_ADDRESS* paipForwarders,
  3022. DWORD* pdwForwardTimeout, DWORD* pfSlave)
  3023. {
  3024. ASSERT(m_pServInfoEx->m_pServInfo != NULL);
  3025. // return pointers to struct fields, caller has to copy data elsewhere
  3026. *pdwForwardTimeout = m_pServInfoEx->m_pServInfo->dwForwardTimeout;
  3027. *pfSlave = m_pServInfoEx->m_pServInfo->fSlave;
  3028. if (m_pServInfoEx->m_pServInfo->aipForwarders == NULL)
  3029. {
  3030. *pcForwardersCount = 0;
  3031. *paipForwarders = NULL;
  3032. }
  3033. else
  3034. {
  3035. *pcForwardersCount = m_pServInfoEx->m_pServInfo->aipForwarders->AddrCount;
  3036. *paipForwarders = m_pServInfoEx->m_pServInfo->aipForwarders->AddrArray;
  3037. }
  3038. }
  3039. CDNSRootHintsNode* CDNSServerNode::GetRootHints()
  3040. {
  3041. if (m_pRootHintsNode == NULL)
  3042. {
  3043. m_pRootHintsNode = new CDNSRootHintsNode;
  3044. ASSERT(m_pRootHintsNode != NULL);
  3045. m_pRootHintsNode->SetServerNode(GetServerNode());
  3046. }
  3047. return m_pRootHintsNode;
  3048. }
  3049. void CDNSServerNode::GetTestOptions(CDNSServerTestOptions* pOptions)
  3050. {
  3051. ASSERT(pOptions != NULL);
  3052. *pOptions = m_testOptions;
  3053. }
  3054. void CDNSServerNode::ResetTestOptions(CDNSServerTestOptions* pOptions)
  3055. {
  3056. ASSERT(pOptions != NULL);
  3057. m_testOptions = *pOptions;
  3058. CDNSRootData* pSnapinData = (CDNSRootData*)GetRootContainer();
  3059. pSnapinData->SetDirtyFlag(TRUE);
  3060. }
  3061. void CDNSServerNode::AddTestQueryResult(CDNSServerTestQueryResult* pTestResult,
  3062. CComponentDataObject* pComponentData)
  3063. {
  3064. // TRACE(_T("m_testResultList.GetCount() == %d\n"), m_testResultList.GetCount());
  3065. if (!pTestResult->m_bAsyncQuery)
  3066. m_bTestQueryPending = FALSE;
  3067. CDNSServerTestQueryResultList::addAction action =
  3068. m_testResultList.AddTestQueryResult(pTestResult);
  3069. // change icon, if necessary (GetImageIndex() will switch from/to alternative server icon set
  3070. if (action == CDNSServerTestQueryResultList::added ||
  3071. action == CDNSServerTestQueryResultList::addedAndRemoved)
  3072. {
  3073. ASSERT(IsVisible());
  3074. VERIFY(SUCCEEDED(pComponentData->ChangeNode(this, CHANGE_RESULT_ITEM_ICON)));
  3075. if (m_bPrevQuerySuccess != m_testResultList.LastQuerySuceeded())
  3076. {
  3077. pComponentData->UpdateResultPaneView(this);
  3078. }
  3079. m_bPrevQuerySuccess = m_testResultList.LastQuerySuceeded();
  3080. }
  3081. pComponentData->GetPropertyPageHolderTable()->BroadcastMessageToSheets(
  3082. this, SHEET_MSG_SERVER_TEST_DATA,
  3083. (LPARAM)action);
  3084. }
  3085. /////////////////////////////////////////////////////////////////////////////
  3086. ///////// LOW LEVEL DNS UTILITIES ///////////////////////////////////////////
  3087. /////////////////////////////////////////////////////////////////////////////
  3088. DNS_STATUS CDNSServerNode::EnumZoneInfo(CZoneInfoHolder* pZoneInfoHolder)
  3089. {
  3090. return EnumZoneInfo(m_szDisplayName, pZoneInfoHolder);
  3091. }
  3092. DNS_STATUS CDNSServerNode::EnumZoneInfo(LPCTSTR, CZoneInfoHolder* pZoneInfoHolder)
  3093. {
  3094. ASSERT(pZoneInfoHolder != NULL);
  3095. USES_CONVERSION;
  3096. DNS_STATUS err = 0;
  3097. do
  3098. {
  3099. ASSERT(pZoneInfoHolder->m_dwArrSize > 0);
  3100. ASSERT(pZoneInfoHolder->m_dwZoneCount == 0);
  3101. ASSERT(pZoneInfoHolder->m_zoneInfoArray != NULL);
  3102. if ((err == 0) || (err != ERROR_MORE_DATA))
  3103. {
  3104. break; // success or no need to retry
  3105. }
  3106. if (!pZoneInfoHolder->Grow())
  3107. {
  3108. break; // reached the limit for growth
  3109. }
  3110. } while (TRUE);
  3111. return err;
  3112. }
  3113. DNS_STATUS CDNSServerNode::ClearCache()
  3114. {
  3115. USES_CONVERSION;
  3116. return ::DnssrvOperation(GetRPCName(), // server name
  3117. NULL, // zone name, just pass null
  3118. DNSSRV_OP_CLEAR_CACHE,
  3119. DNSSRV_TYPEID_NULL,
  3120. NULL);
  3121. }
  3122. void CDNSServerNode::FreeServInfo()
  3123. {
  3124. ASSERT(m_pServInfoEx != NULL);
  3125. m_pServInfoEx->FreeInfo();
  3126. }
  3127. DNS_STATUS CDNSServerNode::GetServInfo()
  3128. {
  3129. ASSERT(m_pServInfoEx != NULL);
  3130. return m_pServInfoEx->Query(GetDisplayName());
  3131. }
  3132. void CDNSServerNode::AttachServerInfo(CDNSServerInfoEx* pNewInfo)
  3133. {
  3134. ASSERT(pNewInfo != NULL);
  3135. ASSERT(m_pServInfoEx != NULL);
  3136. delete m_pServInfoEx;
  3137. m_pServInfoEx = pNewInfo;
  3138. }
  3139. void CDNSServerNode::FreeRootHints()
  3140. {
  3141. if (m_pRootHintsNode != NULL)
  3142. {
  3143. //CNodeList* pChildList = m_pRootHintsNode->GetChildList();
  3144. //int n = pChildList->GetCount();
  3145. delete m_pRootHintsNode;
  3146. m_pRootHintsNode = NULL;
  3147. }
  3148. }
  3149. void CDNSServerNode::AttachRootHints(CDNSRootHintsNode* pNewRootHints)
  3150. {
  3151. ASSERT(pNewRootHints != NULL);
  3152. FreeRootHints();
  3153. m_pRootHintsNode = pNewRootHints;
  3154. // the display and full names were set already in the constructor
  3155. m_pRootHintsNode->SetServerNode(GetServerNode());
  3156. }