Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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