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

2003 lines
52 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: zone.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 "domain.h"
  18. #include "record.h"
  19. #include "zone.h"
  20. #ifdef DEBUG_ALLOCATOR
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. #endif
  27. ////////////////////////////////////////////////////////////////////////////
  28. // CDNSZoneNode
  29. // {720132B9-44B2-11d1-B92F-00A0C9A06D2D}
  30. const GUID CDNSZoneNode::NodeTypeGUID =
  31. { 0x720132b9, 0x44b2, 0x11d1, { 0xb9, 0x2f, 0x0, 0xa0, 0xc9, 0xa0, 0x6d, 0x2d } };
  32. extern ZONE_TYPE_MAP _ZoneTypeStrings[];
  33. CDNSZoneNode::CDNSZoneNode()
  34. {
  35. ASSERT(!IsDelegation());
  36. m_pZoneNode = this; // the zone is us
  37. m_pZoneInfoEx = new CDNSZoneInfoEx; // empty object with no data inside
  38. // data valid when zone info not available
  39. m_dwZoneFlags = 0x0;
  40. m_wZoneType = 0x0;
  41. NullCachedPointers();
  42. }
  43. CDNSZoneNode::~CDNSZoneNode()
  44. {
  45. TRACE(_T("~CDNSZoneNode(), name <%s>\n"),GetDisplayName());
  46. if (m_pZoneInfoEx != NULL)
  47. delete m_pZoneInfoEx;
  48. }
  49. #ifdef USE_NDNC
  50. ReplicationType CDNSZoneNode::GetDirectoryPartitionFlagsAsReplType()
  51. {
  52. ReplicationType replReturn = w2k;
  53. DWORD dwFlags = GetDirectoryPartitionFlags();
  54. if (dwFlags & DNS_DP_DOMAIN_DEFAULT)
  55. {
  56. replReturn = domain;
  57. }
  58. else if (dwFlags & DNS_DP_FOREST_DEFAULT)
  59. {
  60. replReturn = forest;
  61. }
  62. else
  63. {
  64. if (dwFlags & DNS_DP_LEGACY)
  65. {
  66. replReturn = w2k;
  67. }
  68. else
  69. {
  70. replReturn = custom;
  71. }
  72. }
  73. return replReturn;
  74. }
  75. PCWSTR CDNSZoneNode::GetCustomPartitionName()
  76. {
  77. USES_CONVERSION;
  78. ASSERT(m_pZoneInfoEx != NULL);
  79. if (m_szPartitionName.IsEmpty() && m_pZoneInfoEx->HasData())
  80. {
  81. m_szPartitionName = UTF8_TO_W(m_pZoneInfoEx->m_pZoneInfo->pszDpFqdn);
  82. }
  83. return m_szPartitionName;
  84. }
  85. DNS_STATUS CDNSZoneNode::ChangeDirectoryPartitionType(ReplicationType type, PCWSTR pszCustomPartition)
  86. {
  87. USES_CONVERSION;
  88. PSTR pszReplScope = 0;
  89. switch (type)
  90. {
  91. case domain :
  92. pszReplScope = DNS_DP_DOMAIN_STR;
  93. break;
  94. case forest :
  95. pszReplScope = DNS_DP_FOREST_STR;
  96. break;
  97. case w2k :
  98. pszReplScope = DNS_DP_LEGACY_STR;
  99. break;
  100. default :
  101. pszReplScope = W_TO_UTF8(pszCustomPartition);
  102. break;
  103. }
  104. DNS_STATUS dwErr = ::DnssrvChangeZoneDirectoryPartition(GetServerNode()->GetRPCName(),
  105. W_TO_UTF8(GetFullName()),
  106. pszReplScope);
  107. if (dwErr == 0)
  108. {
  109. GetZoneInfo();
  110. }
  111. return dwErr;
  112. }
  113. #endif // USE_NDNC
  114. LPCWSTR CDNSZoneNode::GetString(int nCol)
  115. {
  116. switch (nCol)
  117. {
  118. case 0:
  119. //
  120. // Zone name
  121. //
  122. return GetDisplayName();
  123. case 1:
  124. //
  125. // Zone type
  126. //
  127. {
  128. if (GetZoneType() == DNS_ZONE_TYPE_PRIMARY && IsDSIntegrated())
  129. {
  130. return _ZoneTypeStrings[0].szBuffer;
  131. }
  132. if (GetZoneType() == DNS_ZONE_TYPE_SECONDARY)
  133. {
  134. return _ZoneTypeStrings[2].szBuffer;
  135. }
  136. if (GetZoneType() == DNS_ZONE_TYPE_STUB)
  137. {
  138. if (IsDSIntegrated())
  139. {
  140. return _ZoneTypeStrings[6].szBuffer;
  141. }
  142. else
  143. {
  144. return _ZoneTypeStrings[5].szBuffer;
  145. }
  146. }
  147. //
  148. // Standard primary
  149. //
  150. return _ZoneTypeStrings[1].szBuffer;
  151. }
  152. /* case 2:
  153. //
  154. // Directory Partition Name
  155. //
  156. {
  157. CDNSServerNode* pServerNode = GetServerNode();
  158. if (!IsDSIntegrated() ||
  159. pServerNode->GetBuildNumber() < DNS_SRV_BUILD_NUMBER_WHISTLER ||
  160. (pServerNode->GetMajorVersion() <= DNS_SRV_MAJOR_VERSION_NT_5 &&
  161. pServerNode->GetMinorVersion() < DNS_SRV_MINOR_VERSION_WHISTLER))
  162. {
  163. //
  164. // The zone is not DS integrated
  165. // or
  166. // this is a pre-Whistler server, no Application Directory Partition support
  167. //
  168. return g_lpszNullString;
  169. }
  170. DWORD dwDpFlags = GetDirectoryPartitionFlags();
  171. if (dwDpFlags == 0 ||
  172. dwDpFlags & DNS_DP_LEGACY)
  173. {
  174. //
  175. // To all DCs in the domain
  176. //
  177. // REVIEW_JEFFJON : todo!!!
  178. return g_lpszNullString;
  179. }
  180. else if (dwDpFlags & DNS_DP_DOMAIN_DEFAULT)
  181. {
  182. //
  183. // To all DNS servers in the domain
  184. //
  185. // REVIEW_JEFFJON : todo!!!
  186. return g_lpszNullString;
  187. }
  188. else if (dwDpFlags & DNS_DP_ENTERPRISE_DEFAULT)
  189. {
  190. //
  191. // To all DNS servers in the forest
  192. //
  193. // REVIEW_JEFFJON : todo!!!
  194. return g_lpszNullString;
  195. }
  196. else if (dwDpFlags & DNS_DP_ENLISTED)
  197. {
  198. //
  199. // To all DCs in the application directory partition
  200. //
  201. return GetCustomPartitionName();
  202. }
  203. }
  204. break;
  205. */
  206. case 2:
  207. //
  208. // Status
  209. //
  210. {
  211. if (IsPaused())
  212. {
  213. return _ZoneTypeStrings[4].szBuffer;
  214. }
  215. return _ZoneTypeStrings[3].szBuffer;
  216. }
  217. }
  218. return g_lpszNullString;
  219. }
  220. void CDNSZoneNode::InitializeFromRPCZoneInfo(PDNS_RPC_ZONE pZoneInfo, BOOL bAdvancedView)
  221. {
  222. USES_CONVERSION;
  223. ASSERT(m_pZoneInfoEx != NULL);
  224. ASSERT(!m_pZoneInfoEx->HasData());
  225. ASSERT(pZoneInfo != NULL);
  226. m_dwZoneFlags = 0x0;
  227. if (pZoneInfo->Flags.Paused) m_dwZoneFlags |= DNS_ZONE_Paused;
  228. if (pZoneInfo->Flags.Shutdown) m_dwZoneFlags |= DNS_ZONE_Shutdown;
  229. if (pZoneInfo->Flags.Reverse) m_dwZoneFlags |= DNS_ZONE_Reverse;
  230. if (pZoneInfo->Flags.AutoCreated) m_dwZoneFlags |= DNS_ZONE_AutoCreated;
  231. if (pZoneInfo->Flags.DsIntegrated) m_dwZoneFlags |= DNS_ZONE_DsIntegrated;
  232. m_wZoneType = pZoneInfo->ZoneType;
  233. SetNames(IsZone(), pZoneInfo->Flags.Reverse, bAdvancedView,
  234. pZoneInfo->pszZoneName, pZoneInfo->pszZoneName);
  235. }
  236. void CDNSZoneNode::FreeZoneInfo()
  237. {
  238. ASSERT(m_pZoneInfoEx != NULL);
  239. m_pZoneInfoEx->FreeInfo();
  240. }
  241. DNS_STATUS CDNSZoneNode::GetZoneInfo()
  242. {
  243. ASSERT(m_pZoneInfoEx != NULL);
  244. CDNSServerNode* pServerNode = GetServerNode();
  245. ASSERT(pServerNode != NULL);
  246. return m_pZoneInfoEx->Query(pServerNode->GetRPCName(),
  247. GetFullName(),
  248. pServerNode->GetVersion());
  249. }
  250. void CDNSZoneNode::AttachZoneInfo(CDNSZoneInfoEx* pNewInfo)
  251. {
  252. ASSERT(pNewInfo != NULL);
  253. if (m_pZoneInfoEx != NULL)
  254. delete m_pZoneInfoEx;
  255. m_pZoneInfoEx = pNewInfo;
  256. }
  257. void CDNSZoneNode::SetZoneNormalViewHelper(CString& szDisplayName)
  258. {
  259. // the display name is stripped of the "in-addr.arpa" suffix
  260. // e.g. from "127.in-addr.arpa" to "127"
  261. // e.g. from "55.157.in-addr.arpa" to "55.157"
  262. BOOL bArpa = RemoveInAddrArpaSuffix(szDisplayName.GetBuffer(1));
  263. szDisplayName.ReleaseBuffer();
  264. if (!bArpa)
  265. return;
  266. LPWSTR lpsz1 = szDisplayName.GetBuffer(1);
  267. int nOctects = ReverseIPString(lpsz1);
  268. //ASSERT(nOctects > 0 && nOctects < 4);
  269. szDisplayName.ReleaseBuffer(); // got "157.80"
  270. switch(nOctects)
  271. {
  272. case 1:
  273. szDisplayName += _T(".x.x.x Subnet");
  274. break;
  275. case 2:
  276. szDisplayName += _T(".x.x Subnet");
  277. break;
  278. case 3:
  279. szDisplayName += _T(".x Subnet");
  280. break;
  281. }
  282. }
  283. void CDNSZoneNode::ChangeViewOption(BOOL bAdvanced,
  284. CComponentDataObject* pComponentDataObject)
  285. {
  286. ASSERT(IsReverse());
  287. if (!IsReverse())
  288. return;
  289. // change the display name
  290. m_szDisplayName = GetFullName();
  291. if (!bAdvanced)
  292. {
  293. SetZoneNormalViewHelper(m_szDisplayName);
  294. }
  295. if(IsVisible())
  296. VERIFY(SUCCEEDED(pComponentDataObject->ChangeNode(this, CHANGE_RESULT_ITEM_DATA)));
  297. // change the display name for all PTR records in the tree
  298. ChangePTRRecordsViewOption(bAdvanced, pComponentDataObject);
  299. }
  300. BOOL CDNSZoneNode::OnAddMenuItem(LPCONTEXTMENUITEM2 pContextMenuItem2,
  301. long *pInsertionAllowed)
  302. {
  303. DWORD dwType = GetZoneType();
  304. //
  305. // call this before the base class because it filters it out
  306. //
  307. if (pContextMenuItem2->lCommandID == IDM_ZONE_TRANSFER ||
  308. pContextMenuItem2->lCommandID == IDM_ZONE_RELOAD_FROM_MASTER)
  309. {
  310. //
  311. // if it is not a secondary, just bail out
  312. //
  313. if ( (dwType != DNS_ZONE_TYPE_SECONDARY) && (dwType != DNS_ZONE_TYPE_STUB))
  314. {
  315. return FALSE;
  316. }
  317. //
  318. // have the menu item added. but it might be grayed out...
  319. //
  320. if (IsThreadLocked() || (m_nState == notLoaded) || (m_nState == loading))
  321. {
  322. //
  323. // thread locked or not loaded state
  324. //
  325. pContextMenuItem2->fFlags |= MF_GRAYED;
  326. }
  327. return TRUE;
  328. }
  329. if (pContextMenuItem2->lCommandID == IDM_ZONE_UPDATE_DATA_FILE)
  330. {
  331. //
  332. // cannot update data file on secondary zones, the cache or autocreated zones
  333. //
  334. if ( (dwType != DNS_ZONE_TYPE_PRIMARY) || IsAutocreated() )
  335. {
  336. return FALSE;
  337. }
  338. //
  339. // have the menu item added. but it might be grayed out...
  340. //
  341. if (m_nState != loaded)
  342. {
  343. //
  344. // not loaded state
  345. //
  346. pContextMenuItem2->fFlags |= MF_GRAYED;
  347. }
  348. else if ( (dwType == DNS_ZONE_TYPE_PRIMARY) && IsDSIntegrated() )
  349. {
  350. //
  351. // primaries DS integrated
  352. //
  353. pContextMenuItem2->fFlags |= MF_GRAYED;
  354. }
  355. return TRUE;
  356. }
  357. if (pContextMenuItem2->lCommandID == IDM_ZONE_RELOAD)
  358. {
  359. //
  360. // cannot reload the cache or autocreated zones
  361. //
  362. if ( (dwType == DNS_ZONE_TYPE_CACHE) || IsAutocreated() )
  363. {
  364. return FALSE;
  365. }
  366. //
  367. // have the menu item added. but it might be grayed out...
  368. //
  369. if (IsThreadLocked() || (m_nState != loaded))
  370. {
  371. // not loaded state
  372. pContextMenuItem2->fFlags |= MF_GRAYED;
  373. }
  374. return TRUE;
  375. }
  376. //
  377. // NOTE: the base class knows about the derived class, so must call like this
  378. //
  379. if (!CDNSDomainNode::OnAddMenuItem(pContextMenuItem2,pInsertionAllowed))
  380. {
  381. return FALSE;
  382. }
  383. return TRUE;
  384. }
  385. BOOL CDNSZoneNode::OnSetRenameVerbState(DATA_OBJECT_TYPES,
  386. BOOL* pbHide,
  387. CNodeList*)
  388. {
  389. // REVIEW_JEFFJON : removed from Whistler release
  390. //*pbHide = FALSE;
  391. //return TRUE;
  392. *pbHide = TRUE;
  393. return FALSE;
  394. }
  395. HRESULT CDNSZoneNode::OnRename(CComponentDataObject*,
  396. LPWSTR lpszNewName)
  397. {
  398. TRACE(_T("CDNSZoneNode::OnRename() : new name = %ws\n"), lpszNewName);
  399. return S_FALSE;
  400. }
  401. HRESULT CDNSZoneNode::GetResultViewType(CComponentDataObject*,
  402. LPOLESTR *ppViewType,
  403. long *pViewOptions)
  404. {
  405. HRESULT hr = S_FALSE;
  406. BOOL bUseMessageView = FALSE;
  407. DWORD dwType = GetZoneType();
  408. // special case for paused/expired zones
  409. switch (m_nState)
  410. {
  411. case loaded:
  412. {
  413. if (dwType == DNS_ZONE_TYPE_CACHE)
  414. {
  415. bUseMessageView = FALSE;
  416. }
  417. else // authoritated zone
  418. {
  419. if (IsPaused())
  420. bUseMessageView = FALSE;
  421. else if (IsExpired())
  422. bUseMessageView = TRUE;
  423. else
  424. bUseMessageView = FALSE;
  425. }
  426. }
  427. break;
  428. case unableToLoad:
  429. case accessDenied:
  430. bUseMessageView = TRUE;
  431. break;
  432. default:
  433. bUseMessageView = FALSE;
  434. }
  435. if (bUseMessageView)
  436. {
  437. *pViewOptions = MMC_VIEW_OPTIONS_NOLISTVIEWS;
  438. LPOLESTR psz = NULL;
  439. StringFromCLSID(CLSID_MessageView, &psz);
  440. USES_CONVERSION;
  441. if (psz != NULL)
  442. {
  443. *ppViewType = psz;
  444. hr = S_OK;
  445. }
  446. }
  447. else
  448. {
  449. *pViewOptions = MMC_VIEW_OPTIONS_MULTISELECT;
  450. *ppViewType = NULL;
  451. hr = S_FALSE;
  452. }
  453. return hr;
  454. }
  455. HRESULT CDNSZoneNode::OnShow(LPCONSOLE lpConsole)
  456. {
  457. CComPtr<IUnknown> spUnknown;
  458. CComPtr<IMessageView> spMessageView;
  459. HRESULT hr = lpConsole->QueryResultView(&spUnknown);
  460. if (FAILED(hr))
  461. return S_OK;
  462. hr = spUnknown->QueryInterface(IID_IMessageView, (PVOID*)&spMessageView);
  463. if (SUCCEEDED(hr))
  464. {
  465. CString szTitle, szMessage;
  466. IconIdentifier iconID;
  467. DWORD dwType = GetZoneType();
  468. if ((dwType == DNS_ZONE_TYPE_PRIMARY) && IsDSIntegrated())
  469. {
  470. VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_ZONE_NOT_LOADED_TITLE));
  471. VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_ZONE_NOT_LOADED_DS_MESSAGE));
  472. iconID = Icon_Error;
  473. }
  474. else if ((dwType == DNS_ZONE_TYPE_PRIMARY) && !IsDSIntegrated())
  475. {
  476. VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_ZONE_NOT_LOADED_TITLE));
  477. VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_ZONE_NOT_LOADED_PRIMARY_MESSAGE));
  478. iconID = Icon_Error;
  479. }
  480. else
  481. {
  482. VERIFY(szTitle.LoadString(IDS_MESSAGE_VIEW_ZONE_NOT_LOADED_TITLE));
  483. VERIFY(szMessage.LoadString(IDS_MESSAGE_VIEW_ZONE_NOT_LOADED_SECONDARY_MESSAGE));
  484. iconID = Icon_Error;
  485. }
  486. spMessageView->SetTitleText(szTitle);
  487. spMessageView->SetBodyText(szMessage);
  488. spMessageView->SetIcon(iconID);
  489. }
  490. return S_OK;
  491. }
  492. int CDNSZoneNode::GetImageIndex(BOOL)
  493. {
  494. DWORD dwType = GetZoneType();
  495. BOOL bPrimary = (dwType == DNS_ZONE_TYPE_PRIMARY);
  496. // special case for paused/expired zones
  497. int nIndex = -1;
  498. switch (m_nState)
  499. {
  500. case notLoaded:
  501. nIndex = (bPrimary) ? ZONE_IMAGE_NOT_LOADED_1 : ZONE_IMAGE_NOT_LOADED_2;
  502. break;
  503. case loading:
  504. nIndex = (bPrimary) ? ZONE_IMAGE_LOADING_1 : ZONE_IMAGE_LOADING_2;
  505. break;
  506. case loaded:
  507. {
  508. if (dwType == DNS_ZONE_TYPE_CACHE)
  509. {
  510. nIndex = (bPrimary) ? ZONE_IMAGE_LOADED_1 : ZONE_IMAGE_LOADED_2;
  511. }
  512. else // authoritated zone
  513. {
  514. if (IsPaused())
  515. nIndex = (bPrimary) ? ZONE_IMAGE_PAUSED_1 : ZONE_IMAGE_PAUSED_2;
  516. else if (IsExpired())
  517. nIndex = (bPrimary) ? ZONE_IMAGE_EXPIRED_1 : ZONE_IMAGE_EXPIRED_2;
  518. else
  519. nIndex = (bPrimary) ? ZONE_IMAGE_LOADED_1 : ZONE_IMAGE_LOADED_2;
  520. }
  521. }
  522. break;
  523. case unableToLoad:
  524. nIndex = (bPrimary) ? ZONE_IMAGE_UNABLE_TO_LOAD_1 : ZONE_IMAGE_UNABLE_TO_LOAD_2;
  525. break;
  526. case accessDenied:
  527. nIndex = (bPrimary) ? ZONE_IMAGE_ACCESS_DENIED_1 : ZONE_IMAGE_ACCESS_DENIED_2;
  528. break;
  529. default:
  530. ASSERT(FALSE);
  531. }
  532. ASSERT(nIndex > 0);
  533. return nIndex;
  534. }
  535. HRESULT CDNSZoneNode::OnCommand(long nCommandID,
  536. DATA_OBJECT_TYPES,
  537. CComponentDataObject* pComponentData,
  538. CNodeList* pNodeList)
  539. {
  540. if (pNodeList->GetCount() > 1) // multiple selection
  541. {
  542. return E_FAIL;
  543. }
  544. switch (nCommandID)
  545. {
  546. case IDM_DOMAIN_NEW_DOMAIN:
  547. OnNewDomain(pComponentData);
  548. break;
  549. case IDM_DOMAIN_NEW_DELEGATION:
  550. OnNewDelegation(pComponentData);
  551. break;
  552. case IDM_DOMAIN_NEW_RECORD:
  553. OnNewRecord(pComponentData, pNodeList);
  554. break;
  555. case IDM_DOMAIN_NEW_HOST:
  556. OnNewHost(pComponentData);
  557. break;
  558. case IDM_DOMAIN_NEW_ALIAS:
  559. OnNewAlias(pComponentData);
  560. break;
  561. case IDM_DOMAIN_NEW_MX:
  562. OnNewMailExchanger(pComponentData);
  563. break;
  564. case IDM_DOMAIN_NEW_PTR:
  565. OnNewPointer(pComponentData);
  566. break;
  567. case IDM_ZONE_UPDATE_DATA_FILE:
  568. OnUpdateDataFile(pComponentData);
  569. break;
  570. case IDM_ZONE_RELOAD:
  571. OnReload(pComponentData);
  572. break;
  573. case IDM_ZONE_TRANSFER:
  574. OnTransferFromMaster(pComponentData);
  575. break;
  576. case IDM_ZONE_RELOAD_FROM_MASTER:
  577. OnReloadFromMaster(pComponentData);
  578. break;
  579. case IDM_SNAPIN_ADVANCED_VIEW:
  580. ((CDNSRootData*)pComponentData->GetRootData())->OnViewOptions(pComponentData);
  581. break;
  582. case IDM_SNAPIN_FILTERING:
  583. {
  584. if (((CDNSRootData*)pComponentData->GetRootData())->OnFilteringOptions(pComponentData))
  585. {
  586. pComponentData->SetDescriptionBarText(this);
  587. }
  588. }
  589. break;
  590. default:
  591. ASSERT(FALSE); // Unknown command!
  592. return E_FAIL;
  593. }
  594. return S_OK;
  595. }
  596. void CDNSZoneNode::OnUpdateDataFile(CComponentDataObject* pComponentData)
  597. {
  598. // if there are sheets up, ask to close them down, because a
  599. // failure would "Red X" the server and remove all the children
  600. if (IsSheetLocked())
  601. {
  602. if (!CanCloseSheets())
  603. return;
  604. pComponentData->GetPropertyPageHolderTable()->DeleteSheetsOfNode(this);
  605. }
  606. ASSERT(m_nState == loaded);
  607. OnChangeState(pComponentData); // move to loading
  608. { // scope for the wait cursor
  609. CWaitCursor wait;
  610. m_dwErr = WriteToDatabase();
  611. }
  612. // if there is a failure, remove all children,
  613. // will need a refresh to get them back
  614. if (m_dwErr != 0)
  615. {
  616. RemoveAllChildrenHelper(pComponentData);
  617. ASSERT(!HasChildren());
  618. }
  619. OnChangeState(pComponentData); // move to loaded or unableToLoad
  620. }
  621. void CDNSZoneNode::OnReload(CComponentDataObject* pComponentData)
  622. {
  623. UINT nRet = DNSConfirmOperation(IDS_MSG_ZONE_RELOAD, this);
  624. if (IDCANCEL == nRet ||
  625. IDNO == nRet)
  626. {
  627. return;
  628. }
  629. // if there are sheets up, ask to close them down, because
  630. // we will need a refresh
  631. if (IsSheetLocked())
  632. {
  633. if (!CanCloseSheets())
  634. return;
  635. pComponentData->GetPropertyPageHolderTable()->DeleteSheetsOfNode(this);
  636. }
  637. ASSERT(m_nState == loaded);
  638. DNS_STATUS err;
  639. { // scope for the wait cursor
  640. CWaitCursor wait;
  641. err = Reload();
  642. }
  643. if (err != 0)
  644. {
  645. // need to let the user know the operation failed
  646. DNSErrorDialog(err, IDS_MSG_ZONE_FAIL_RELOAD);
  647. return;
  648. }
  649. CNodeList nodeList;
  650. nodeList.AddTail(this);
  651. // the zone has been reloaded cause a refresh to get new data
  652. VERIFY(OnRefresh(pComponentData, &nodeList));
  653. }
  654. void CDNSZoneNode::OnTransferFromMaster(CComponentDataObject* pComponentData)
  655. {
  656. // if there are sheets up, ask to close them down, because
  657. // we will need a refresh
  658. if (IsSheetLocked())
  659. {
  660. if (!CanCloseSheets())
  661. return;
  662. pComponentData->GetPropertyPageHolderTable()->DeleteSheetsOfNode(this);
  663. }
  664. ASSERT(m_nState != notLoaded);
  665. ASSERT(m_nState != loading);
  666. DNS_STATUS err;
  667. { // scope for the wait cursor
  668. CWaitCursor wait;
  669. err = TransferFromMaster();
  670. }
  671. if (err != 0)
  672. {
  673. // need to let the user know the operation failed
  674. DNSErrorDialog(err, IDS_MSG_ZONE_FAIL_TRANSFER);
  675. return;
  676. }
  677. CNodeList nodeList;
  678. nodeList.AddTail(this);
  679. // the zone has been reloaded cause a refresh to get new data
  680. VERIFY(OnRefresh(pComponentData, &nodeList));
  681. }
  682. void CDNSZoneNode::OnReloadFromMaster(CComponentDataObject* pComponentData)
  683. {
  684. // if there are sheets up, ask to close them down, because
  685. // we will need a refresh
  686. if (IsSheetLocked())
  687. {
  688. if (!CanCloseSheets())
  689. return;
  690. pComponentData->GetPropertyPageHolderTable()->DeleteSheetsOfNode(this);
  691. }
  692. ASSERT(m_nState != notLoaded);
  693. ASSERT(m_nState != loading);
  694. DNS_STATUS err;
  695. { // scope for the wait cursor
  696. CWaitCursor wait;
  697. err = ReloadFromMaster();
  698. }
  699. if (err != 0)
  700. {
  701. // need to let the user know the operation failed
  702. DNSErrorDialog(err, IDS_MSG_ZONE_FAIL_RELOAD_FROM_MASTER);
  703. return;
  704. }
  705. CNodeList nodeList;
  706. nodeList.AddTail(this);
  707. // the zone has been reloaded cause a refresh to get new data
  708. VERIFY(OnRefresh(pComponentData, &nodeList));
  709. }
  710. void CDNSZoneNode::OnDelete(CComponentDataObject* pComponentData,
  711. CNodeList* pNodeList)
  712. {
  713. if (pNodeList->GetCount() > 1) // multiple selection
  714. {
  715. OnMultiselectDelete(pComponentData, pNodeList);
  716. return;
  717. }
  718. UINT nRet = DNSConfirmOperation(IDS_MSG_ZONE_DELETE, this);
  719. if (IDCANCEL == nRet ||
  720. IDNO == nRet)
  721. {
  722. return;
  723. }
  724. BOOL bDeleteFromDS = FALSE;
  725. if (((GetZoneType() == DNS_ZONE_TYPE_PRIMARY) || (GetZoneType() == DNS_ZONE_TYPE_STUB)) &&
  726. IsDSIntegrated())
  727. {
  728. if (GetServerNode()->GetBootMethod() == BOOT_METHOD_DIRECTORY)
  729. {
  730. // ask confirmation on delete from DS
  731. int nRetVal = DNSMessageBox(IDS_MSG_ZONE_DELETE_FROM_DS_BOOT3,
  732. MB_YESNO | MB_DEFBUTTON2);
  733. if (IDNO == nRetVal)
  734. return;
  735. bDeleteFromDS = TRUE;
  736. }
  737. else
  738. {
  739. // ask confirmation on delete from DS
  740. int nRetVal = DNSMessageBox(IDS_MSG_ZONE_DELETE_FROM_DS,
  741. MB_YESNOCANCEL | MB_DEFBUTTON3);
  742. if (IDCANCEL == nRetVal)
  743. return;
  744. bDeleteFromDS = (nRetVal == IDYES);
  745. }
  746. }
  747. if (IsSheetLocked())
  748. {
  749. if (IDCANCEL == DNSMessageBox(IDS_ZONE_WARNING_SHEETS_UP, MB_OKCANCEL))
  750. return;
  751. pComponentData->GetPropertyPageHolderTable()->DeleteSheetsOfNode(this);
  752. }
  753. ASSERT(!IsSheetLocked());
  754. DNS_STATUS err = Delete(bDeleteFromDS);
  755. if (err != 0)
  756. {
  757. DNSErrorDialog(err, IDS_MSG_ZONE_FAIL_DELETE);
  758. return;
  759. }
  760. // now remove from the UI and from the cache
  761. DeleteHelper(pComponentData);
  762. pComponentData->UpdateResultPaneView(GetContainer());
  763. if (IsRootZone())
  764. {
  765. if (DNSMessageBox(IDS_MSG_ZONE_DELETE_ROOT, MB_YESNO) == IDYES)
  766. {
  767. GetServerNode()->SetProppageStart(3); // 3 signifies the Root Hints page
  768. pComponentData->CreatePropertySheet(GetServerNode(), NULL, L"My Title");
  769. }
  770. }
  771. delete this; // gone
  772. }
  773. BOOL CDNSZoneNode::HasPropertyPages(DATA_OBJECT_TYPES,
  774. BOOL* pbHideVerb,
  775. CNodeList* pNodeList)
  776. {
  777. if (pNodeList->GetCount() > 1) // multiple selection
  778. {
  779. return FALSE;
  780. }
  781. *pbHideVerb = FALSE; // always show the verb
  782. if (!m_bHasDataForPropPages)
  783. return FALSE;
  784. // cannot have property pages only in loaded state
  785. // if (m_nState != loaded)
  786. // return FALSE;
  787. ASSERT(m_pZoneInfoEx != NULL);
  788. if ( (!m_pZoneInfoEx->HasData()) ||
  789. ( (GetZoneType() == DNS_ZONE_TYPE_CACHE) || IsAutocreated() ) )
  790. {
  791. return FALSE;
  792. }
  793. return TRUE;
  794. }
  795. HRESULT CDNSZoneNode::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider,
  796. LONG_PTR handle,
  797. CNodeList* pNodeList)
  798. {
  799. ASSERT(pNodeList->GetCount() == 1); // multi-select not supported
  800. ASSERT(m_bHasDataForPropPages);
  801. if (GetSheetCount() > 0)
  802. {
  803. CComponentDataObject* pComponentDataObject =
  804. ((CRootData*)(GetContainer()->GetRootContainer()))->GetComponentDataObject();
  805. ASSERT(pComponentDataObject != NULL);
  806. pComponentDataObject->GetPropertyPageHolderTable()->BroadcastSelectPage(this, ZONE_HOLDER_GEN);
  807. return S_OK;
  808. }
  809. return CreatePropertyPagesHelper(lpProvider, handle, ZONE_HOLDER_GEN);
  810. }
  811. HRESULT CDNSZoneNode::CreatePropertyPagesHelper(LPPROPERTYSHEETCALLBACK lpProvider,
  812. LONG_PTR handle, long nStartPageCode)
  813. {
  814. CComponentDataObject* pComponentDataObject =
  815. ((CRootData*)(GetContainer()->GetRootContainer()))->GetComponentDataObject();
  816. ASSERT(pComponentDataObject != NULL);
  817. CDNSZonePropertyPageHolder* pHolder =
  818. new CDNSZonePropertyPageHolder((CCathegoryFolderNode*)GetContainer(), this, pComponentDataObject);
  819. ASSERT(pHolder != NULL);
  820. pHolder->SetStartPageCode(nStartPageCode);
  821. pHolder->SetSheetTitle(IDS_PROP_SHEET_TITLE_FMT, this);
  822. return pHolder->CreateModelessSheet(lpProvider, handle);
  823. }
  824. void CDNSZoneNode::Show(BOOL bShow, CComponentDataObject* pComponentData)
  825. {
  826. CDNSDomainNode::Show(bShow, pComponentData);
  827. if (!bShow)
  828. NullCachedPointers();
  829. }
  830. void CDNSZoneNode::NullCachedPointers()
  831. {
  832. m_pSOARecordNode = NULL;
  833. m_pWINSRecordNode = NULL;
  834. }
  835. BOOL CDNSZoneNode::OnRefresh(CComponentDataObject* pComponentData,
  836. CNodeList* pNodeList)
  837. {
  838. if (pNodeList->GetCount() > 1) // multiple selection
  839. {
  840. BOOL bRet = TRUE;
  841. POSITION pos = pNodeList->GetHeadPosition();
  842. while (pos != NULL)
  843. {
  844. CTreeNode* pNode = pNodeList->GetNext(pos);
  845. ASSERT(pNode != NULL);
  846. CNodeList nodeList;
  847. nodeList.AddTail(pNode);
  848. if (!pNode->OnRefresh(pComponentData, &nodeList))
  849. {
  850. bRet = FALSE;
  851. }
  852. }
  853. return bRet;
  854. }
  855. CNodeList nodeList;
  856. nodeList.AddTail(this);
  857. if (CDNSDomainNode::OnRefresh(pComponentData, &nodeList))
  858. {
  859. FreeZoneInfo();
  860. NullCachedPointers();
  861. return TRUE;
  862. }
  863. return FALSE;
  864. }
  865. void CDNSZoneNode::OnHaveData(CObjBase* pObj, CComponentDataObject* pComponentDataObject)
  866. {
  867. // if we get the zone info, just set it and bail out (no UI)
  868. if (IS_CLASS(*pObj, CDNSZoneInfoEx))
  869. {
  870. ASSERT(!HasChildren()); // must be the first one coming from the thread
  871. AttachZoneInfo(dynamic_cast<CDNSZoneInfoEx*>(pObj));
  872. return;
  873. }
  874. CDNSDomainNode::OnHaveData(pObj, pComponentDataObject);
  875. }
  876. void CDNSZoneNode::OnHaveRecord(CDNSRecordNodeBase* pRecordNode,
  877. CComponentDataObject* pComponentDataObject)
  878. {
  879. CDNSDomainNode::OnHaveRecord(pRecordNode, pComponentDataObject);
  880. if ((pRecordNode->GetType() == DNS_TYPE_SOA) && pRecordNode->IsAtTheNode())
  881. {
  882. ASSERT(m_pSOARecordNode == NULL);
  883. m_pSOARecordNode = (CDNS_SOA_RecordNode*)pRecordNode;
  884. }
  885. else if ( ( (pRecordNode->GetType() == DNS_TYPE_WINS) ||
  886. (pRecordNode->GetType() == DNS_TYPE_NBSTAT) ) && pRecordNode->IsAtTheNode() )
  887. {
  888. ASSERT(m_pWINSRecordNode == NULL);
  889. ASSERT( (IsReverse() && pRecordNode->GetType() == DNS_TYPE_NBSTAT) ||
  890. (!IsReverse() && pRecordNode->GetType() == DNS_TYPE_WINS ) );
  891. m_pWINSRecordNode = pRecordNode;
  892. }
  893. }
  894. //////////////////////////////////////////////////////////////////////////////////
  895. DNS_STATUS CDNSZoneNode::CreatePrimary(LPCTSTR lpszDBName,
  896. BOOL bLoadExisting,
  897. BOOL bDSIntegrated,
  898. UINT nDynamicUpdate)
  899. {
  900. USES_CONVERSION;
  901. DWORD dwZoneType = DNS_ZONE_TYPE_PRIMARY;
  902. IP_ADDRESS adwIpAddressDummy = 0;
  903. LPCWSTR lpszServerName = GetServerNode()->GetRPCName();
  904. LPCSTR lpszAnsiZoneName = W_TO_UTF8(GetFullName());
  905. // create the zone
  906. DNS_STATUS err = ::DnssrvCreateZone(
  907. lpszServerName,
  908. lpszAnsiZoneName,
  909. dwZoneType, // Zone type
  910. NULL, // RNAME field should be NULL according to bug 135245
  911. 0, // Number of masters, NA for primary
  912. &adwIpAddressDummy, // Array of masters, dummy for primary
  913. bLoadExisting,
  914. bDSIntegrated,
  915. bDSIntegrated ? NULL : W_TO_UTF8(lpszDBName), // Database file
  916. 0,
  917. 0);
  918. if (err != 0)
  919. return err;
  920. // set the dynamic update flag
  921. err = ::DnssrvResetDwordProperty(lpszServerName, lpszAnsiZoneName,
  922. DNS_REGKEY_ZONE_ALLOW_UPDATE, nDynamicUpdate);
  923. if (err != 0)
  924. return err;
  925. ASSERT(m_pZoneInfoEx != NULL);
  926. return GetZoneInfo();
  927. }
  928. #ifdef USE_NDNC
  929. DNS_STATUS CDNSZoneNode::CreatePrimaryInDirectoryPartition(BOOL bLoadExisting,
  930. UINT nDynamicUpdate,
  931. ReplicationType replType,
  932. PCWSTR pszPartitionName)
  933. {
  934. USES_CONVERSION;
  935. DWORD dwZoneType = DNS_ZONE_TYPE_PRIMARY;
  936. IP_ADDRESS adwIpAddressDummy = 0;
  937. DWORD dwPartitionFlags = 0;
  938. switch (replType)
  939. {
  940. case forest:
  941. dwPartitionFlags |= DNS_DP_FOREST_DEFAULT;
  942. break;
  943. case domain:
  944. dwPartitionFlags |= DNS_DP_DOMAIN_DEFAULT;
  945. break;
  946. case w2k:
  947. dwPartitionFlags |= DNS_DP_LEGACY;
  948. break;
  949. case custom:
  950. dwPartitionFlags = 0;
  951. break;
  952. case none:
  953. default:
  954. ASSERT(FALSE);
  955. break;
  956. }
  957. LPCWSTR lpszServerName = GetServerNode()->GetRPCName();
  958. LPCSTR lpszAnsiZoneName = W_TO_UTF8(GetFullName());
  959. LPCSTR lpszUTF8PartitionName = W_TO_UTF8(pszPartitionName);
  960. // create the zone
  961. DNS_STATUS err = ::DnssrvCreateZoneInDirectoryPartition(
  962. lpszServerName,
  963. lpszAnsiZoneName,
  964. dwZoneType, // Zone type
  965. NULL, // RNAME field should be NULL according to bug 135245
  966. 0, // Number of masters, NA for primary
  967. &adwIpAddressDummy, // Array of masters, dummy for primary
  968. bLoadExisting,
  969. 0, // dwTimeout
  970. 0, // fSlave
  971. dwPartitionFlags,
  972. (replType == custom) ? lpszUTF8PartitionName : NULL);
  973. if (err != 0)
  974. return err;
  975. // set the dynamic update flag
  976. err = ::DnssrvResetDwordProperty(lpszServerName, lpszAnsiZoneName,
  977. DNS_REGKEY_ZONE_ALLOW_UPDATE, nDynamicUpdate);
  978. if (err != 0)
  979. return err;
  980. ASSERT(m_pZoneInfoEx != NULL);
  981. return GetZoneInfo();
  982. }
  983. DNS_STATUS CDNSZoneNode::CreateStubInDirectoryPartition(DWORD* ipMastersArray,
  984. int nIPMastersCount,
  985. BOOL bLoadExisting,
  986. ReplicationType replType,
  987. PCWSTR pszPartitionName)
  988. {
  989. USES_CONVERSION;
  990. DWORD dwZoneType = DNS_ZONE_TYPE_STUB;
  991. DWORD dwPartitionFlags = 0;
  992. switch (replType)
  993. {
  994. case forest:
  995. dwPartitionFlags |= DNS_DP_FOREST_DEFAULT;
  996. break;
  997. case domain:
  998. dwPartitionFlags |= DNS_DP_DOMAIN_DEFAULT;
  999. break;
  1000. case w2k:
  1001. dwPartitionFlags |= DNS_DP_LEGACY;
  1002. break;
  1003. case custom:
  1004. dwPartitionFlags = 0;
  1005. break;
  1006. case none:
  1007. default:
  1008. ASSERT(FALSE);
  1009. break;
  1010. }
  1011. ASSERT(ipMastersArray != NULL);
  1012. ASSERT(nIPMastersCount > 0);
  1013. LPCWSTR lpszServerName = GetServerNode()->GetRPCName();
  1014. LPCSTR lpszAnsiZoneName = W_TO_UTF8(GetFullName());
  1015. LPCSTR lpszUTF8PartitionName = W_TO_UTF8(pszPartitionName);
  1016. // create the zone
  1017. DNS_STATUS err = ::DnssrvCreateZoneInDirectoryPartition(
  1018. lpszServerName,
  1019. lpszAnsiZoneName,
  1020. dwZoneType, // Zone type
  1021. NULL, // RNAME field should be NULL according to bug 135245
  1022. nIPMastersCount, // Number of masters, NA for primary
  1023. ipMastersArray, // Array of masters, dummy for primary
  1024. bLoadExisting,
  1025. 0, // dwTimeout
  1026. 0, // fSlave
  1027. dwPartitionFlags,
  1028. (replType == custom) ? lpszUTF8PartitionName : NULL);
  1029. if (err != 0)
  1030. return err;
  1031. ASSERT(m_pZoneInfoEx != NULL);
  1032. return GetZoneInfo();
  1033. }
  1034. #endif // USE_NDNC
  1035. DNS_STATUS CDNSZoneNode::CreateSecondary(DWORD* ipMastersArray, int nIPMastersCount,
  1036. LPCTSTR lpszDBName, BOOL bLoadExisting)
  1037. {
  1038. USES_CONVERSION;
  1039. DWORD dwZoneType = DNS_ZONE_TYPE_SECONDARY;
  1040. ASSERT(ipMastersArray != NULL);
  1041. ASSERT(nIPMastersCount > 0);
  1042. DNS_STATUS err = ::DnssrvCreateZone(
  1043. GetServerNode()->GetRPCName(), // Server name
  1044. W_TO_UTF8(GetFullName()), // Zone name
  1045. dwZoneType, // Zone type
  1046. NULL, // RNAME field should be NULL according to bug 135245
  1047. (DWORD)nIPMastersCount, // Number of masters
  1048. ipMastersArray, // Array of masters
  1049. bLoadExisting,
  1050. FALSE, // fDSIntegrated (secondaries are not in the DS)
  1051. W_TO_UTF8(lpszDBName), // Database file
  1052. 0,
  1053. 0);
  1054. if (err != 0)
  1055. return err;
  1056. ASSERT(m_pZoneInfoEx != NULL);
  1057. return GetZoneInfo();
  1058. }
  1059. DNS_STATUS CDNSZoneNode::CreateStub(DWORD* ipMastersArray,
  1060. int nIPMastersCount,
  1061. LPCTSTR lpszDBName,
  1062. BOOL bLoadExisting,
  1063. BOOL bDSIntegrated)
  1064. {
  1065. USES_CONVERSION;
  1066. DWORD dwZoneType = DNS_ZONE_TYPE_STUB;
  1067. ASSERT(ipMastersArray != NULL);
  1068. ASSERT(nIPMastersCount > 0);
  1069. DNS_STATUS err = ::DnssrvCreateZone(
  1070. GetServerNode()->GetRPCName(), // Server name
  1071. W_TO_UTF8(GetFullName()), // Zone name
  1072. dwZoneType, // Zone type
  1073. NULL, // RNAME field should be NULL according to bug 135245
  1074. (DWORD)nIPMastersCount, // Number of masters
  1075. ipMastersArray, // Array of masters
  1076. bLoadExisting,
  1077. bDSIntegrated,
  1078. (bDSIntegrated) ? NULL : W_TO_UTF8(lpszDBName), // Database file
  1079. 0,
  1080. 0);
  1081. if (err != 0)
  1082. return err;
  1083. ASSERT(m_pZoneInfoEx != NULL);
  1084. return GetZoneInfo();
  1085. }
  1086. DNS_STATUS CDNSZoneNode::CreateForwarder(DWORD* ipMastersArray,
  1087. int nIPMastersCount,
  1088. DWORD dwTimeout,
  1089. DWORD fSlave)
  1090. {
  1091. USES_CONVERSION;
  1092. DWORD dwZoneType = DNS_ZONE_TYPE_FORWARDER;
  1093. DNS_STATUS err = ::DnssrvCreateZone(
  1094. GetServerNode()->GetRPCName(), // Server name
  1095. W_TO_UTF8(GetFullName()), // Zone name
  1096. dwZoneType, // Zone type
  1097. NULL, // RNAME field should be NULL according to bug 135245
  1098. (DWORD)nIPMastersCount, // Number of masters
  1099. ipMastersArray, // Array of masters
  1100. FALSE, // Load existing?
  1101. FALSE, // fDSIntegrated (secondaries are not in the DS)
  1102. NULL, // Database file
  1103. dwTimeout, // Time out
  1104. fSlave); // Slave?
  1105. if (err != 0)
  1106. return err;
  1107. ASSERT(m_pZoneInfoEx != NULL);
  1108. return GetZoneInfo();
  1109. }
  1110. DNS_STATUS CDNSZoneNode::SetSecondary(DWORD cMasters, PIP_ADDRESS aipMasters,
  1111. DWORD dwLoadOptions, LPCTSTR lpszDataFile)
  1112. {
  1113. USES_CONVERSION;
  1114. ASSERT_VALID_ZONE_INFO();
  1115. if (cMasters == 0)
  1116. return DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP;
  1117. DNS_STATUS err = 0;
  1118. IP_ADDRESS dummy;
  1119. if (aipMasters == NULL)
  1120. {
  1121. ASSERT(cMasters == 0);
  1122. aipMasters = &dummy; // RPC wants non null ip array
  1123. }
  1124. err = ::DnssrvResetZoneTypeEx(GetServerNode()->GetRPCName(), // server name
  1125. W_TO_UTF8(GetFullName()), // zone name
  1126. DNS_ZONE_TYPE_SECONDARY,
  1127. cMasters,
  1128. aipMasters,
  1129. dwLoadOptions,
  1130. FALSE, // bDSIntegrated
  1131. W_TO_UTF8(lpszDataFile));
  1132. if (err == 0)
  1133. err = GetZoneInfo();
  1134. return err;
  1135. }
  1136. DNS_STATUS CDNSZoneNode::SetStub(DWORD cMasters,
  1137. PIP_ADDRESS aipMasters,
  1138. DWORD dwLoadOptions,
  1139. BOOL bDSIntegrated,
  1140. LPCTSTR lpszDataFile,
  1141. BOOL bLocalListOfMasters)
  1142. {
  1143. USES_CONVERSION;
  1144. ASSERT_VALID_ZONE_INFO();
  1145. if (cMasters == 0)
  1146. return DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP;
  1147. DNS_STATUS err = 0;
  1148. IP_ADDRESS dummy;
  1149. if (aipMasters == NULL)
  1150. {
  1151. ASSERT(cMasters == 0);
  1152. aipMasters = &dummy; // RPC wants non null ip array
  1153. }
  1154. err = ::DnssrvResetZoneTypeEx(GetServerNode()->GetRPCName(), // server name
  1155. W_TO_UTF8(GetFullName()), // zone name
  1156. DNS_ZONE_TYPE_STUB,
  1157. cMasters,
  1158. aipMasters,
  1159. dwLoadOptions,
  1160. bDSIntegrated,
  1161. (bDSIntegrated) ? NULL : W_TO_UTF8(lpszDataFile));
  1162. if (err != 0)
  1163. return err;
  1164. if (bLocalListOfMasters)
  1165. {
  1166. err = ::DnssrvResetZoneMastersEx(GetServerNode()->GetRPCName(),
  1167. W_TO_UTF8(GetFullName()),
  1168. cMasters,
  1169. aipMasters,
  1170. TRUE); // LocalListOfMasters
  1171. }
  1172. else
  1173. {
  1174. err = ::DnssrvResetZoneMastersEx(GetServerNode()->GetRPCName(),
  1175. W_TO_UTF8(GetFullName()),
  1176. 0,
  1177. NULL,
  1178. TRUE); // LocalListOfMasters
  1179. }
  1180. if (err == 0)
  1181. err = GetZoneInfo();
  1182. return err;
  1183. }
  1184. DNS_STATUS CDNSZoneNode::SetPrimary(DWORD dwLoadOptions, BOOL bDSIntegrated,
  1185. LPCTSTR lpszDataFile)
  1186. {
  1187. USES_CONVERSION;
  1188. ASSERT_VALID_ZONE_INFO();
  1189. DWORD cDummyMasters = 0; // dummy
  1190. DWORD dwDummyArr = 0;
  1191. DNS_STATUS err = ::DnssrvResetZoneTypeEx(GetServerNode()->GetRPCName(), // server name
  1192. W_TO_UTF8(GetFullName()), // zone name
  1193. DNS_ZONE_TYPE_PRIMARY,
  1194. cDummyMasters, // not neeeded, but have to pass valid RPC val
  1195. &dwDummyArr,
  1196. dwLoadOptions,
  1197. bDSIntegrated,
  1198. bDSIntegrated ? "" : W_TO_UTF8(lpszDataFile));
  1199. if (err == 0)
  1200. err = GetZoneInfo();
  1201. return err;
  1202. }
  1203. DNS_STATUS CDNSZoneNode::SetAgingNoRefreshInterval(DWORD dwNoRefreshInterval)
  1204. {
  1205. ASSERT_VALID_ZONE_INFO();
  1206. USES_CONVERSION;
  1207. DNS_STATUS dwErr = ::DnssrvResetDwordProperty(GetServerNode()->GetRPCName(),
  1208. W_TO_UTF8(GetFullName()),
  1209. DNS_REGKEY_ZONE_NOREFRESH_INTERVAL,
  1210. dwNoRefreshInterval);
  1211. if (dwErr == 0)
  1212. m_pZoneInfoEx->m_pZoneInfo->dwNoRefreshInterval = dwNoRefreshInterval;
  1213. return dwErr;
  1214. }
  1215. DNS_STATUS CDNSZoneNode::SetAgingRefreshInterval(DWORD dwRefreshInterval)
  1216. {
  1217. ASSERT_VALID_ZONE_INFO();
  1218. USES_CONVERSION;
  1219. DNS_STATUS dwErr = ::DnssrvResetDwordProperty(GetServerNode()->GetRPCName(),
  1220. W_TO_UTF8(GetFullName()),
  1221. DNS_REGKEY_ZONE_REFRESH_INTERVAL,
  1222. dwRefreshInterval);
  1223. if (dwErr == 0)
  1224. m_pZoneInfoEx->m_pZoneInfo->dwRefreshInterval = dwRefreshInterval;
  1225. return dwErr;
  1226. }
  1227. DNS_STATUS CDNSZoneNode::SetScavengingEnabled(BOOL bEnable)
  1228. {
  1229. ASSERT_VALID_ZONE_INFO();
  1230. USES_CONVERSION;
  1231. DNS_STATUS dwErr = ::DnssrvResetDwordProperty(GetServerNode()->GetRPCName(),
  1232. W_TO_UTF8(GetFullName()),
  1233. DNS_REGKEY_ZONE_AGING,
  1234. bEnable);
  1235. if (dwErr == 0)
  1236. m_pZoneInfoEx->m_pZoneInfo->fAging = bEnable;
  1237. return dwErr;
  1238. }
  1239. DNS_STATUS CDNSZoneNode::Delete(BOOL bDeleteFromDs)
  1240. {
  1241. ASSERT(m_pZoneInfoEx != NULL);
  1242. USES_CONVERSION;
  1243. if (((GetZoneType() == DNS_ZONE_TYPE_PRIMARY) ||
  1244. (GetZoneType() == DNS_ZONE_TYPE_STUB) ||
  1245. (GetZoneType() == DNS_ZONE_TYPE_FORWARDER)) &&
  1246. IsDSIntegrated() && bDeleteFromDs)
  1247. {
  1248. return ::DnssrvOperation(GetServerNode()->GetRPCName(), // server name
  1249. W_TO_UTF8(GetFullName()),
  1250. DNSSRV_OP_ZONE_DELETE_FROM_DS,
  1251. DNSSRV_TYPEID_NULL,
  1252. NULL);
  1253. }
  1254. else
  1255. {
  1256. return ::DnssrvDeleteZone(GetServerNode()->GetRPCName(),
  1257. W_TO_UTF8(GetFullName()));
  1258. }
  1259. }
  1260. DNS_STATUS CDNSZoneNode::IncrementVersion()
  1261. {
  1262. ASSERT(GetZoneType() == DNS_ZONE_TYPE_PRIMARY);
  1263. ASSERT(!IsAutocreated());
  1264. ASSERT(m_pZoneInfoEx != NULL);
  1265. USES_CONVERSION;
  1266. DNS_STATUS err = ::DnssrvIncrementZoneVersion(GetServerNode()->GetRPCName(),
  1267. W_TO_UTF8(GetFullName()));
  1268. // refresh Zone Info if already present
  1269. if ((err == 0) && m_pZoneInfoEx->HasData())
  1270. err = GetZoneInfo();
  1271. return err;
  1272. }
  1273. DNS_STATUS CDNSZoneNode::Reload()
  1274. {
  1275. ASSERT(GetZoneType() == DNS_ZONE_TYPE_PRIMARY);
  1276. ASSERT(!IsAutocreated());
  1277. ASSERT(m_pZoneInfoEx != NULL);
  1278. USES_CONVERSION;
  1279. return ::DnssrvOperation(GetServerNode()->GetRPCName(), // server name
  1280. W_TO_UTF8(GetFullName()),
  1281. DNSSRV_OP_ZONE_RELOAD,
  1282. DNSSRV_TYPEID_NULL,
  1283. NULL);
  1284. }
  1285. DNS_STATUS CDNSZoneNode::TransferFromMaster()
  1286. {
  1287. ASSERT(GetZoneType() == DNS_ZONE_TYPE_SECONDARY || GetZoneType() == DNS_ZONE_TYPE_STUB);
  1288. ASSERT(!IsAutocreated());
  1289. ASSERT(m_pZoneInfoEx != NULL);
  1290. USES_CONVERSION;
  1291. return ::DnssrvOperation(GetServerNode()->GetRPCName(), // server name
  1292. W_TO_UTF8(GetFullName()),
  1293. DNSSRV_OP_ZONE_REFRESH,
  1294. DNSSRV_TYPEID_NULL,
  1295. NULL);
  1296. }
  1297. DNS_STATUS CDNSZoneNode::ReloadFromMaster()
  1298. {
  1299. ASSERT(GetZoneType() == DNS_ZONE_TYPE_SECONDARY || GetZoneType() == DNS_ZONE_TYPE_STUB);
  1300. ASSERT(!IsAutocreated());
  1301. ASSERT(m_pZoneInfoEx != NULL);
  1302. USES_CONVERSION;
  1303. return ::DnssrvOperation(GetServerNode()->GetRPCName(), // server name
  1304. W_TO_UTF8(GetFullName()),
  1305. DNSSRV_OP_ZONE_EXPIRE,
  1306. DNSSRV_TYPEID_NULL,
  1307. NULL);
  1308. }
  1309. PCWSTR CDNSZoneNode::GetDN()
  1310. {
  1311. ASSERT(IsDSIntegrated());
  1312. ASSERT(m_pZoneInfoEx);
  1313. ASSERT(m_pZoneInfoEx->HasData());
  1314. return m_pZoneInfoEx->m_pZoneInfo->pwszZoneDn;
  1315. }
  1316. BOOL CDNSZoneNode::IsDSIntegrated()
  1317. {
  1318. if (GetZoneType() == DNS_ZONE_TYPE_CACHE)
  1319. return FALSE;
  1320. ASSERT(m_pZoneInfoEx != NULL);
  1321. return (m_pZoneInfoEx->HasData()) ?
  1322. (m_pZoneInfoEx->m_pZoneInfo->fUseDatabase ? TRUE : FALSE):
  1323. ((m_dwZoneFlags & DNS_ZONE_DsIntegrated) != 0);
  1324. }
  1325. //sz = _T("LDAP://DC=uidev-one,DC=ntdev,DC=Microsoft,DC=Com,O=Internet");
  1326. void CDNSZoneNode::GetDataFile(CString& szName)
  1327. {
  1328. ASSERT_VALID_ZONE_INFO();
  1329. USES_CONVERSION;
  1330. if (m_pZoneInfoEx == NULL || m_pZoneInfoEx->m_pZoneInfo == NULL)
  1331. {
  1332. szName = L"";
  1333. }
  1334. else
  1335. {
  1336. szName = UTF8_TO_W(m_pZoneInfoEx->m_pZoneInfo->pszDataFile);
  1337. }
  1338. }
  1339. LPCSTR CDNSZoneNode::GetDataFile()
  1340. {
  1341. ASSERT_VALID_ZONE_INFO();
  1342. if (m_pZoneInfoEx == NULL || m_pZoneInfoEx->m_pZoneInfo == NULL)
  1343. {
  1344. return "";
  1345. }
  1346. return m_pZoneInfoEx->m_pZoneInfo->pszDataFile;
  1347. }
  1348. DNS_STATUS CDNSZoneNode::ResetDatabase(BOOL bDSIntegrated, LPCTSTR lpszDataFile)
  1349. {
  1350. ASSERT_VALID_ZONE_INFO();
  1351. USES_CONVERSION;
  1352. DNS_STATUS err = ::DnssrvResetZoneDatabase(GetServerNode()->GetRPCName(), // server name
  1353. W_TO_UTF8(GetFullName()), // zone name
  1354. bDSIntegrated,
  1355. W_TO_UTF8(lpszDataFile));
  1356. if (err == 0)
  1357. err = GetZoneInfo();
  1358. return err;
  1359. }
  1360. DNS_STATUS CDNSZoneNode::WriteToDatabase()
  1361. {
  1362. ASSERT_VALID_ZONE_INFO();
  1363. return CDNSZoneNode::WriteToDatabase(GetServerNode()->GetRPCName(), // server name
  1364. GetFullName()); // zone name
  1365. }
  1366. DNS_STATUS CDNSZoneNode::WriteToDatabase(LPCWSTR lpszServer, LPCWSTR lpszZone)
  1367. {
  1368. USES_CONVERSION;
  1369. return ::DnssrvOperation(lpszServer, W_TO_UTF8(lpszZone),
  1370. DNSSRV_OP_ZONE_WRITE_BACK_FILE,
  1371. DNSSRV_TYPEID_NULL,
  1372. NULL);
  1373. }
  1374. DNS_STATUS CDNSZoneNode::WriteToDatabase(LPCWSTR lpszServer, LPCSTR lpszZone)
  1375. {
  1376. return ::DnssrvOperation(lpszServer, lpszZone,
  1377. DNSSRV_OP_ZONE_WRITE_BACK_FILE,
  1378. DNSSRV_TYPEID_NULL,
  1379. NULL);
  1380. }
  1381. UINT CDNSZoneNode::GetDynamicUpdate()
  1382. {
  1383. ASSERT_VALID_ZONE_INFO();
  1384. return m_pZoneInfoEx->m_pZoneInfo->fAllowUpdate;
  1385. // return m_pZoneInfoEx->m_nAllowsDynamicUpdate;
  1386. }
  1387. DNS_STATUS CDNSZoneNode::SetDynamicUpdate(UINT nDynamic)
  1388. {
  1389. ASSERT_VALID_ZONE_INFO();
  1390. DNS_STATUS err = 0;
  1391. // call only if the info is dirty
  1392. if (GetDynamicUpdate() != nDynamic)
  1393. {
  1394. USES_CONVERSION;
  1395. err = ::DnssrvResetDwordProperty(GetServerNode()->GetRPCName(), // server name
  1396. m_pZoneInfoEx->m_pZoneInfo->pszZoneName,
  1397. DNS_REGKEY_ZONE_ALLOW_UPDATE,
  1398. nDynamic);
  1399. if (err != 0)
  1400. return err;
  1401. err = GetZoneInfo();
  1402. }
  1403. return err;
  1404. }
  1405. DNS_STATUS CDNSZoneNode::ResetSecondaries(DWORD fSecureSecondaries,
  1406. DWORD cSecondaries, PIP_ADDRESS aipSecondaries,
  1407. DWORD fNotifyLevel,
  1408. DWORD cNotify, PIP_ADDRESS aipNotify)
  1409. {
  1410. ASSERT_VALID_ZONE_INFO();
  1411. DNS_STATUS err = 0;
  1412. BOOL bSecondariesDirty = (m_pZoneInfoEx->m_pZoneInfo->fSecureSecondaries != fSecureSecondaries) ||
  1413. (m_pZoneInfoEx->m_pZoneInfo->fNotifyLevel != fNotifyLevel) ||
  1414. (!(m_pZoneInfoEx->m_pZoneInfo->aipSecondaries == NULL && cSecondaries == 0) &&
  1415. (
  1416. (m_pZoneInfoEx->m_pZoneInfo->aipSecondaries == NULL && cSecondaries > 0) || // no addr --> more than one
  1417. (m_pZoneInfoEx->m_pZoneInfo->aipSecondaries->AddrCount != cSecondaries) || // change the # of addresses
  1418. (memcmp(aipSecondaries, m_pZoneInfoEx->m_pZoneInfo->aipSecondaries->AddrArray, sizeof(IP_ADDRESS)*cSecondaries) != 0)
  1419. )
  1420. );
  1421. BOOL bNotifyDirty =
  1422. (!(m_pZoneInfoEx->m_pZoneInfo->aipNotify == NULL && cNotify == 0) &&
  1423. (
  1424. (m_pZoneInfoEx->m_pZoneInfo->aipNotify == NULL && cNotify > 0) || // no addr --> more than one
  1425. (m_pZoneInfoEx->m_pZoneInfo->aipNotify->AddrCount != cNotify) || // change the # of addresses
  1426. (memcmp(aipNotify, m_pZoneInfoEx->m_pZoneInfo->aipNotify->AddrArray, sizeof(IP_ADDRESS)*cNotify) != 0)
  1427. )
  1428. );
  1429. if (bSecondariesDirty || bNotifyDirty)
  1430. {
  1431. USES_CONVERSION;
  1432. err = ::DnssrvResetZoneSecondaries(GetServerNode()->GetRPCName(), // server name
  1433. W_TO_UTF8(GetFullName()), // zone name
  1434. fSecureSecondaries,
  1435. cSecondaries,
  1436. aipSecondaries,
  1437. fNotifyLevel,
  1438. cNotify,
  1439. aipNotify
  1440. );
  1441. }
  1442. if (err == 0)
  1443. err = GetZoneInfo();
  1444. return err;
  1445. }
  1446. void CDNSZoneNode::GetSecondariesInfo(DWORD* pfSecureSecondaries,
  1447. DWORD* pcSecondaries, PIP_ADDRESS* paipSecondaries,
  1448. DWORD* pfNotifyLevel,
  1449. DWORD* pcNotify, PIP_ADDRESS* paipNotify)
  1450. {
  1451. ASSERT_VALID_ZONE_INFO();
  1452. ASSERT(pfSecureSecondaries != NULL);
  1453. ASSERT(pcSecondaries != NULL);
  1454. ASSERT(paipSecondaries != NULL);
  1455. ASSERT(pfNotifyLevel != NULL);
  1456. ASSERT(pcNotify != NULL);
  1457. ASSERT(paipNotify != NULL);
  1458. *pfSecureSecondaries = m_pZoneInfoEx->m_pZoneInfo->fSecureSecondaries;
  1459. // return pointers to struct fields, caller has to copy data elsewhere
  1460. if (m_pZoneInfoEx->m_pZoneInfo->aipSecondaries == NULL)
  1461. {
  1462. *pcSecondaries = 0;
  1463. *paipSecondaries = NULL;
  1464. }
  1465. else
  1466. {
  1467. *pcSecondaries = m_pZoneInfoEx->m_pZoneInfo->aipSecondaries->AddrCount;
  1468. *paipSecondaries = m_pZoneInfoEx->m_pZoneInfo->aipSecondaries->AddrArray;
  1469. }
  1470. *pfNotifyLevel = m_pZoneInfoEx->m_pZoneInfo->fNotifyLevel;
  1471. // return pointers to struct fields, caller has to copy data elsewhere
  1472. if (m_pZoneInfoEx->m_pZoneInfo->aipNotify == NULL)
  1473. {
  1474. *pcNotify = 0;
  1475. *paipNotify = NULL;
  1476. }
  1477. else
  1478. {
  1479. *pcNotify = m_pZoneInfoEx->m_pZoneInfo->aipNotify->AddrCount;
  1480. *paipNotify = m_pZoneInfoEx->m_pZoneInfo->aipNotify->AddrArray;
  1481. }
  1482. }
  1483. DNS_STATUS CDNSZoneNode::ResetMasters(DWORD cMasters, PIP_ADDRESS aipMasters, BOOL bLocalMasters)
  1484. {
  1485. ASSERT_VALID_ZONE_INFO();
  1486. if (cMasters == 0)
  1487. return DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP;
  1488. USES_CONVERSION;
  1489. // make the call only if the data is dirty
  1490. DNS_STATUS err = 0;
  1491. if ((m_pZoneInfoEx->m_pZoneInfo->aipMasters == NULL && cMasters > 0) || // no addr --> more than one
  1492. (m_pZoneInfoEx->m_pZoneInfo->aipMasters->AddrCount != cMasters) || // change the # of addresses
  1493. (memcmp(aipMasters, m_pZoneInfoEx->m_pZoneInfo->aipMasters->AddrArray, sizeof(IP_ADDRESS)*cMasters) != 0) )
  1494. {
  1495. IP_ADDRESS dummy;
  1496. if (aipMasters == NULL)
  1497. {
  1498. ASSERT(cMasters == 0);
  1499. aipMasters = &dummy; // RPC wants non null ip array
  1500. }
  1501. err = ::DnssrvResetZoneMastersEx(GetServerNode()->GetRPCName(), // server name
  1502. W_TO_UTF8(GetFullName()), // zone name
  1503. cMasters,
  1504. aipMasters,
  1505. bLocalMasters);
  1506. if (!bLocalMasters)
  1507. {
  1508. //
  1509. // Reset local list of masters
  1510. //
  1511. err = ::DnssrvResetZoneMastersEx(GetServerNode()->GetRPCName(), // server name
  1512. W_TO_UTF8(GetFullName()), // zone name
  1513. 0,
  1514. NULL,
  1515. TRUE); // LocalListOfMasters
  1516. if (err != 0)
  1517. return err;
  1518. }
  1519. }
  1520. if (err == 0)
  1521. err = GetZoneInfo();
  1522. return err;
  1523. }
  1524. void CDNSZoneNode::GetMastersInfo(DWORD* pcAddrCount, PIP_ADDRESS* ppipAddrs)
  1525. {
  1526. ASSERT_VALID_ZONE_INFO();
  1527. ASSERT(pcAddrCount != NULL);
  1528. ASSERT(ppipAddrs != NULL);
  1529. // return pointers to struct fields, caller has to copy data elsewhere
  1530. if (m_pZoneInfoEx->m_pZoneInfo->aipMasters == NULL)
  1531. {
  1532. *pcAddrCount = 0;
  1533. *ppipAddrs = NULL;
  1534. }
  1535. else
  1536. {
  1537. *pcAddrCount = m_pZoneInfoEx->m_pZoneInfo->aipMasters->AddrCount;
  1538. *ppipAddrs = m_pZoneInfoEx->m_pZoneInfo->aipMasters->AddrArray;
  1539. }
  1540. }
  1541. void CDNSZoneNode::GetLocalListOfMasters(DWORD* pcAddrCount, PIP_ADDRESS* ppipAddrs)
  1542. {
  1543. ASSERT_VALID_ZONE_INFO();
  1544. ASSERT(pcAddrCount != NULL);
  1545. ASSERT(ppipAddrs != NULL);
  1546. // return pointers to struct fields, caller has to copy data elsewhere
  1547. if (m_pZoneInfoEx->m_pZoneInfo->aipLocalMasters == NULL)
  1548. {
  1549. *pcAddrCount = 0;
  1550. *ppipAddrs = NULL;
  1551. }
  1552. else
  1553. {
  1554. *pcAddrCount = m_pZoneInfoEx->m_pZoneInfo->aipLocalMasters->AddrCount;
  1555. *ppipAddrs = m_pZoneInfoEx->m_pZoneInfo->aipLocalMasters->AddrArray;
  1556. }
  1557. }
  1558. DNS_STATUS CDNSZoneNode::TogglePauseHelper(CComponentDataObject* pComponentData)
  1559. {
  1560. ASSERT(m_nState == loaded);
  1561. OnChangeState(pComponentData); // move to loading
  1562. m_dwErr = TogglePause();
  1563. OnChangeState(pComponentData); // move to loaded or unableToLoad
  1564. return (DNS_STATUS)m_dwErr;
  1565. }
  1566. DNS_STATUS CDNSZoneNode::TogglePause()
  1567. {
  1568. ASSERT_VALID_ZONE_INFO();
  1569. USES_CONVERSION;
  1570. DNS_STATUS err;
  1571. if (IsPaused())
  1572. err = ::DnssrvResumeZone(GetServerNode()->GetRPCName(),
  1573. W_TO_UTF8(GetFullName()) // zone name
  1574. );
  1575. else
  1576. err = ::DnssrvPauseZone(GetServerNode()->GetRPCName(),
  1577. W_TO_UTF8(GetFullName()) // zone name
  1578. );
  1579. if (err != 0)
  1580. return err;
  1581. err = GetZoneInfo();
  1582. ASSERT(err == 0);
  1583. return err;
  1584. }
  1585. BOOL CDNSZoneNode::IsPaused()
  1586. {
  1587. if (m_pZoneInfoEx != NULL && m_pZoneInfoEx->HasData())
  1588. {
  1589. ASSERT_VALID_ZONE_INFO();
  1590. return m_pZoneInfoEx->m_pZoneInfo->fPaused;
  1591. }
  1592. return ((m_dwZoneFlags & DNS_ZONE_Paused) != 0);
  1593. }
  1594. BOOL CDNSZoneNode::IsExpired()
  1595. {
  1596. ASSERT(m_pZoneInfoEx != NULL);
  1597. return (m_pZoneInfoEx->HasData()) ? m_pZoneInfoEx->m_pZoneInfo->fShutdown :
  1598. ((m_dwZoneFlags & DNS_ZONE_Shutdown) != 0);
  1599. }
  1600. //////////////////////////////////////////////////////////////////////////
  1601. // editing API's for special record types
  1602. CDNS_SOA_Record* CDNSZoneNode::GetSOARecordCopy()
  1603. {
  1604. ASSERT(m_pSOARecordNode != NULL);
  1605. if (m_pSOARecordNode == NULL)
  1606. return NULL;
  1607. return (CDNS_SOA_Record*)m_pSOARecordNode->CreateCloneRecord();
  1608. }
  1609. DNS_STATUS CDNSZoneNode::UpdateSOARecord(CDNS_SOA_Record* pNewRecord,
  1610. CComponentDataObject* pComponentData)
  1611. {
  1612. ASSERT(m_pSOARecordNode != NULL);
  1613. if (m_pSOARecordNode == NULL)
  1614. {
  1615. return -1;
  1616. }
  1617. DNS_STATUS err = m_pSOARecordNode->Update(pNewRecord, FALSE /*bUseDefaultTTL*/);
  1618. if ( (err == 0) && (pComponentData != NULL) )
  1619. {
  1620. VERIFY(SUCCEEDED(pComponentData->ChangeNode(m_pSOARecordNode, CHANGE_RESULT_ITEM)));
  1621. }
  1622. return err;
  1623. }
  1624. CDNSRecord* CDNSZoneNode::GetWINSRecordCopy()
  1625. {
  1626. ASSERT(m_pWINSRecordNode != NULL);
  1627. if (m_pWINSRecordNode == NULL)
  1628. return NULL;
  1629. return m_pWINSRecordNode->CreateCloneRecord();
  1630. }
  1631. DNS_STATUS CDNSZoneNode::CreateWINSRecord(CDNSRecord* pNewWINSRecord,
  1632. CComponentDataObject* pComponentData)
  1633. {
  1634. TRACE(_T("CDNSZoneNode::CreateWINSRecord()\n"));
  1635. ASSERT(pNewWINSRecord != NULL);
  1636. if (m_pWINSRecordNode != NULL)
  1637. {
  1638. //
  1639. // should never happen
  1640. //
  1641. ASSERT(FALSE && m_pWINSRecordNode == NULL);
  1642. return -1;
  1643. }
  1644. //
  1645. // create a new record node object
  1646. //
  1647. if (IsReverse())
  1648. {
  1649. m_pWINSRecordNode = CDNSRecordInfo::CreateRecordNode(DNS_TYPE_NBSTAT);
  1650. }
  1651. else
  1652. {
  1653. m_pWINSRecordNode = CDNSRecordInfo::CreateRecordNode(DNS_TYPE_WINS);
  1654. }
  1655. //
  1656. // hook up container and set name of node (same as the zone)
  1657. //
  1658. m_pWINSRecordNode->SetContainer(this);
  1659. m_pWINSRecordNode->SetRecordName(GetDisplayName(), TRUE /*bAtTheNode */);
  1660. CDNSRootData* pRootData = (CDNSRootData*)(pComponentData->GetRootData());
  1661. ASSERT(pRootData != NULL);
  1662. m_pWINSRecordNode->SetFlagsDown(TN_FLAG_DNS_RECORD_FULL_NAME, !pRootData->IsAdvancedView());
  1663. //
  1664. // write on server
  1665. //
  1666. DNS_STATUS err = m_pWINSRecordNode->Update(pNewWINSRecord, TRUE /*bUseDefaultTTL*/);
  1667. if (err == 0)
  1668. {
  1669. VERIFY(AddChildToListAndUI(m_pWINSRecordNode, pComponentData));
  1670. pComponentData->SetDescriptionBarText(this);
  1671. }
  1672. else
  1673. {
  1674. delete m_pWINSRecordNode;
  1675. m_pWINSRecordNode = NULL;
  1676. }
  1677. TRACE(_T("EXIT\n"));
  1678. return err;
  1679. }
  1680. DNS_STATUS CDNSZoneNode::UpdateWINSRecord(CDNSRecord* pNewWINSRecord,
  1681. CComponentDataObject* pComponentData)
  1682. {
  1683. TRACE(_T("CDNSZoneNode::UpdateWINSRecord()\n"));
  1684. ASSERT(pNewWINSRecord != NULL);
  1685. ASSERT(m_pWINSRecordNode != NULL);
  1686. if (m_pWINSRecordNode == NULL)
  1687. {
  1688. return -1; // Bogus error code
  1689. }
  1690. ASSERT(
  1691. (IsReverse() && pNewWINSRecord->GetType() == DNS_TYPE_NBSTAT
  1692. && m_pWINSRecordNode->GetType() == DNS_TYPE_NBSTAT) ||
  1693. (!IsReverse() && pNewWINSRecord->GetType() == DNS_TYPE_WINS
  1694. && m_pWINSRecordNode->GetType() == DNS_TYPE_WINS)
  1695. );
  1696. DNS_STATUS err = m_pWINSRecordNode->Update(pNewWINSRecord, TRUE /*bUseDefaultTTL*/);
  1697. if (err == 0)
  1698. {
  1699. VERIFY(SUCCEEDED(pComponentData->ChangeNode(m_pWINSRecordNode, CHANGE_RESULT_ITEM)));
  1700. }
  1701. TRACE(_T("EXIT\n"));
  1702. return err;
  1703. }
  1704. DNS_STATUS CDNSZoneNode::DeleteWINSRecord(CComponentDataObject* pComponentData)
  1705. {
  1706. TRACE(_T("CDNSZoneNode::DeleteWINSRecord()\n"));
  1707. ASSERT(m_pWINSRecordNode != NULL);
  1708. if (m_pWINSRecordNode == NULL)
  1709. {
  1710. return -1; // bogus error code
  1711. }
  1712. DNS_STATUS err = m_pWINSRecordNode->DeleteOnServerAndUI(pComponentData);
  1713. if (err == 0)
  1714. {
  1715. delete m_pWINSRecordNode;
  1716. m_pWINSRecordNode = NULL;
  1717. }
  1718. TRACE(_T("EXIT\n"));
  1719. return err;
  1720. }