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.

3079 lines
92 KiB

  1. /////////////////////////////////////////////////////////////////////
  2. //
  3. // CopyRight ( c ) 1999 Microsoft Corporation
  4. //
  5. // Module Name: DnsWrap.cpp
  6. //
  7. // Description:
  8. // Implementation of dnswrap class
  9. //
  10. // Author:
  11. // Henry Wang ( henrywa ) March 8, 2000
  12. //
  13. //
  14. //////////////////////////////////////////////////////////////////////
  15. #include "DnsWmi.h"
  16. //
  17. // These string tables are in client\print.c
  18. //
  19. extern "C" LPSTR MemTagStringsNT5[];
  20. extern "C" LPSTR MemTagStrings[];
  21. //
  22. // These macros allow us to widen DNS RPC string constants.
  23. //
  24. #define MYTEXT2(str) L##str
  25. #define MYTEXT(str) MYTEXT2(str)
  26. //
  27. // Globals for statistics.
  28. //
  29. struct
  30. {
  31. DWORD dwStatId;
  32. const WCHAR * pszName;
  33. } g_StatInfo[] =
  34. {
  35. { DNSSRV_STATID_TIME, L"Time Stats" },
  36. { DNSSRV_STATID_QUERY, L"Query and Response Stats" },
  37. { DNSSRV_STATID_QUERY2, L"Query Stats" },
  38. { DNSSRV_STATID_RECURSE, L"Recursion Stats" },
  39. { DNSSRV_STATID_MASTER, L"Master Stats" },
  40. { DNSSRV_STATID_SECONDARY, L"Secondary Stats" },
  41. { DNSSRV_STATID_WINS, L"WINS Referral Stats" },
  42. { DNSSRV_STATID_WIRE_UPDATE, L"Packet Dynamic Update Stats" },
  43. { DNSSRV_STATID_SKWANSEC, L"Security Stats" },
  44. { DNSSRV_STATID_DS, L"DS Integration Stats" },
  45. { DNSSRV_STATID_NONWIRE_UPDATE, L"Internal Dynamic Update Stats" },
  46. { DNSSRV_STATID_MEMORY, L"Memory Stats" },
  47. { DNSSRV_STATID_DBASE, L"Database Stats" },
  48. { DNSSRV_STATID_RECORD, L"Record Stats" },
  49. { DNSSRV_STATID_PACKET, L"Packet Memory Usage Stats" },
  50. { DNSSRV_STATID_NBSTAT, L"Nbstat Memory Usage Stats" },
  51. { DNSSRV_STATID_ERRORS, L"Error Stats" },
  52. { DNSSRV_STATID_TIMEOUT, L"Timeout Stats" },
  53. { DNSSRV_STATID_CACHE, L"Query" },
  54. { DNSSRV_STATID_PRIVATE, L"Private Stats" },
  55. { 0, NULL } // terminator
  56. };
  57. //////////////////////////////////////////////////////////////////////
  58. // Construction/Destruction
  59. //////////////////////////////////////////////////////////////////////
  60. CDnsWrap::CDnsWrap()
  61. :m_wszpServerName(NULL)
  62. {
  63. CServerInfo serverInfo;
  64. PDNS_RPC_SERVER_INFO pdata = (PDNS_RPC_SERVER_INFO) serverInfo.m_pInfo;
  65. char* p = pdata->pszServerName;
  66. CharToWchar(p, &m_wszpServerName);
  67. }
  68. CDnsWrap::~CDnsWrap()
  69. {
  70. delete [] m_wszpServerName;
  71. }
  72. CDnsWrap::CServerInfo::CServerInfo()
  73. :m_pInfo(NULL)
  74. {
  75. DWORD dwtypeid;
  76. int status = DnssrvQuery(
  77. PVD_DNS_LOCAL_SERVER,
  78. NULL,
  79. DNSSRV_QUERY_SERVER_INFO,
  80. &dwtypeid,
  81. &m_pInfo);
  82. if(status != ERROR_SUCCESS)
  83. ThrowException(status);
  84. }
  85. CDnsWrap::CServerInfo::~CServerInfo()
  86. {
  87. DnssrvFreeServerInfo((PDNS_RPC_SERVER_INFO)m_pInfo);
  88. }
  89. CDnsWrap& CDnsWrap::DnsObject(void)
  90. {
  91. static CDnsWrap dns;
  92. return dns;
  93. }
  94. /////////////////////////////////////////////////////////////////////////////
  95. //++
  96. //
  97. // Description:
  98. // enumerates record for a give domain. If bRecursive is true, enum all
  99. // records including subdomain, otherwise, enum records directly under
  100. // the domain. It also take a call back function pFilter to allow
  101. // further filtering the records
  102. //
  103. // Arguments:
  104. // objNode [IN ] list of domains
  105. // pFilter [IN] pointer a class contains the criteria
  106. // on how to filter records
  107. // pfFilter [IN] call back function allows further
  108. // processing of records using pFilter
  109. // bRecursive [IN] true for deep enum, otherwise false
  110. // wType, [IN] type of records to enum
  111. // dwFlag, [IN] flag
  112. // pClass, [IN] wmi class for the type of records to enum
  113. // InstMgr [IN] manage wmi object and send them wmi
  114. // Return Value:
  115. // WBEM_S_NO_ERROR
  116. //
  117. //--
  118. /////////////////////////////////////////////////////////////////////////////
  119. SCODE
  120. CDnsWrap::dnsEnumRecordsForDomainEx(
  121. CDomainNode& objNode,
  122. PVOID pFilter,
  123. FILTER pfFilter,
  124. BOOL bRecursive,
  125. WORD wType,
  126. DWORD dwFlag,
  127. IWbemClassObject * pClass,
  128. CWbemInstanceMgr& InstMgr
  129. )
  130. {
  131. CDnsRpcRecordSet RecordSet(
  132. objNode,
  133. wType,
  134. dwFlag,
  135. NULL,
  136. NULL);
  137. PDNS_RPC_NODE pNode=NULL;
  138. WCHAR DomainName[MAX_PATH] = L"";
  139. while (( pNode = RecordSet.GetNextNode()) != NULL)
  140. {
  141. CDnsRpcNode dnsNode;
  142. CObjPath opNew;
  143. if( !dnsNode.Init(pNode))
  144. {
  145. return WBEM_E_FAILED;
  146. }
  147. //find record node
  148. if(dnsNode.IsDomainNode())
  149. {
  150. // get domain name
  151. wstring wstrSubDomainName = dnsNode.GetNodeName();;
  152. wstrSubDomainName += PVD_DNS_LOCAL_SERVER + objNode.wstrNodeName;
  153. CDomainNode subDomain = objNode;
  154. subDomain.wstrNodeName = wstrSubDomainName;
  155. //recursion
  156. if(bRecursive)
  157. {
  158. dnsEnumRecordsForDomainEx(
  159. subDomain,
  160. pFilter,
  161. pfFilter,
  162. bRecursive,
  163. wType,
  164. dwFlag,
  165. pClass,
  166. InstMgr);
  167. }
  168. }
  169. pfFilter(
  170. objNode,
  171. pFilter,
  172. &dnsNode,
  173. pClass,
  174. InstMgr);
  175. }
  176. return WBEM_S_NO_ERROR;
  177. }
  178. SCODE
  179. CDnsWrap::dnsGetDomain(
  180. CObjPath& objParent,
  181. IWbemClassObject* pClass,
  182. IWbemObjectSink* pHandler
  183. )
  184. {
  185. // get top level domain
  186. wstring wstrZoneName = objParent.GetStringValueForProperty(
  187. PVD_DOMAIN_CONTAINER_NAME);
  188. wstring wstrNodeName = objParent.GetStringValueForProperty(
  189. PVD_DOMAIN_FQDN);
  190. list<CDomainNode> nodeList;
  191. dnsEnumDomainForServer(&nodeList);
  192. list<CDomainNode>::iterator i;
  193. BOOL FoundFlag = FALSE;
  194. // check for zone
  195. for(i=nodeList.begin(); i != nodeList.end(); ++i)
  196. {
  197. if(_wcsicmp(
  198. wstrZoneName.data(),
  199. i->wstrZoneName.data()) == 0 )
  200. {
  201. // only roothints and catch, NodeName is initialize to
  202. // nil, we can't do the compare
  203. if(i->wstrNodeName.empty() ||
  204. (_wcsicmp(
  205. wstrNodeName.data(),
  206. i->wstrNodeName.data())==0))
  207. {
  208. FoundFlag = TRUE;
  209. break;
  210. }
  211. }
  212. }
  213. // check for domain in container
  214. if(! FoundFlag)
  215. {
  216. DNS_STATUS status ;
  217. char *pszZoneName=NULL, *pszNodeName=NULL, *pszStartChild=NULL;
  218. DWORD dwBufferLength;
  219. PBYTE pBuffer = NULL;
  220. WcharToChar(wstrZoneName.data(), &pszZoneName);
  221. WcharToChar(wstrNodeName.data(), &pszNodeName);
  222. status = DnssrvEnumRecords(
  223. PVD_DNS_LOCAL_SERVER,
  224. pszZoneName,
  225. pszNodeName,
  226. pszStartChild,
  227. DNS_TYPE_ALL,
  228. DNS_RPC_VIEW_ALL_DATA,
  229. NULL,
  230. NULL,
  231. & dwBufferLength,
  232. & pBuffer);
  233. delete [] pszNodeName;
  234. delete [] pszZoneName;
  235. DnssrvFreeRecordsBuffer(pBuffer);
  236. if (status != ERROR_SUCCESS)
  237. ThrowException(status);
  238. FoundFlag = TRUE;
  239. }
  240. if(FoundFlag)
  241. {
  242. CWbemClassObject Inst;
  243. pClass->SpawnInstance(0, &Inst);
  244. Inst.SetProperty(
  245. wstrNodeName,
  246. PVD_DOMAIN_FQDN);
  247. Inst.SetProperty(
  248. wstrZoneName,
  249. PVD_DOMAIN_CONTAINER_NAME);
  250. Inst.SetProperty(
  251. m_wszpServerName,
  252. PVD_DOMAIN_SERVER_NAME);
  253. // clean up
  254. pHandler->Indicate(1, &Inst);
  255. }
  256. return WBEM_S_NO_ERROR;
  257. }
  258. SCODE
  259. CDnsWrap::dnsDeleteDomain(
  260. char * pszContainer,
  261. char * pszDomain
  262. )
  263. {
  264. LONG status = DnssrvDeleteNode(
  265. PVD_DNS_LOCAL_SERVER,
  266. pszContainer,
  267. pszDomain,
  268. 1 //fDeleteSubtree
  269. );
  270. if ( status != ERROR_SUCCESS )
  271. {
  272. ThrowException(status);
  273. }
  274. return WBEM_S_NO_ERROR;
  275. }
  276. /////////////////////////////////////////////////////////////////////////////
  277. //++
  278. //
  279. // Description:
  280. // enumeratr all zones including cache for local dns server, returns
  281. // them as a list of object path
  282. //
  283. // Arguments:
  284. // pList [IN OUT] list of object path to domains
  285. //
  286. // Return Value:
  287. // WBEM_S_NO_ERROR
  288. //
  289. //--
  290. /////////////////////////////////////////////////////////////////////////////
  291. SCODE
  292. CDnsWrap::dnsEnumDomainForServer(
  293. list<CObjPath>* pList
  294. )
  295. {
  296. PDNS_RPC_ZONE_LIST pZoneList = NULL;
  297. DNS_STATUS status = DnssrvEnumZones(
  298. PVD_DNS_LOCAL_SERVER,
  299. ZONE_REQUEST_ALL_ZONES_AND_CACHE,
  300. NULL,
  301. &pZoneList);
  302. if(status == ERROR_SUCCESS)
  303. {
  304. DNS_RPC_ZONE* pDnsZone = NULL;
  305. CDnsWrap& dns = CDnsWrap::DnsObject();
  306. for(DWORD i = 0; i < pZoneList->dwZoneCount; i++)
  307. {
  308. pDnsZone = (pZoneList->ZoneArray[i]);
  309. if(_wcsicmp(pDnsZone->pszZoneName, PVD_DNS_LOCAL_SERVER))
  310. {
  311. CObjPath opInst;
  312. opInst.SetClass(PVD_CLASS_DOMAIN);
  313. opInst.AddProperty(
  314. PVD_DOMAIN_SERVER_NAME ,
  315. dns.GetServerName().data()
  316. );
  317. opInst.AddProperty(
  318. PVD_DOMAIN_CONTAINER_NAME,
  319. pDnsZone->pszZoneName
  320. );
  321. opInst.AddProperty(
  322. PVD_DOMAIN_FQDN,
  323. pDnsZone->pszZoneName
  324. );
  325. pList->insert(
  326. pList->end(),
  327. opInst);
  328. }
  329. }
  330. // add catch domain
  331. CObjPath opCache;
  332. opCache.SetClass(PVD_CLASS_DOMAIN);
  333. opCache.AddProperty(
  334. PVD_DOMAIN_SERVER_NAME,
  335. dns.GetServerName().data()
  336. );
  337. opCache.AddProperty(
  338. PVD_DOMAIN_CONTAINER_NAME,
  339. PVD_DNS_CACHE
  340. );
  341. opCache.AddProperty(
  342. PVD_DOMAIN_FQDN,
  343. PVD_DNS_CACHE
  344. );
  345. //add roothints
  346. CObjPath opRh;
  347. opRh.SetClass(PVD_CLASS_DOMAIN);
  348. opRh.AddProperty(
  349. PVD_DOMAIN_SERVER_NAME,
  350. dns.GetServerName().data()
  351. );
  352. opRh.AddProperty(
  353. PVD_DOMAIN_CONTAINER_NAME,
  354. PVD_DNS_ROOTHINTS
  355. );
  356. opRh.AddProperty(
  357. PVD_DOMAIN_FQDN,
  358. PVD_DNS_ROOTHINTS
  359. );
  360. pList->insert(pList->begin(), opRh);
  361. pList->insert(pList->begin(), opCache);
  362. }
  363. // CLEAN UP
  364. DnssrvFreeZoneList(pZoneList);
  365. if(status != ERROR_SUCCESS)
  366. {
  367. ThrowException(status);
  368. }
  369. return WBEM_S_NO_ERROR;
  370. }
  371. /////////////////////////////////////////////////////////////////////////////
  372. //++
  373. //
  374. // Description:
  375. // enumeratr all zones including cache for local dns server, returns
  376. // them as a list of domain node
  377. //
  378. // Arguments:
  379. // pList [IN OUT] list of domains
  380. //
  381. // Return Value:
  382. // WBEM_S_NO_ERROR
  383. //
  384. //--
  385. /////////////////////////////////////////////////////////////////////////////
  386. SCODE CDnsWrap::dnsEnumDomainForServer(
  387. list<CDomainNode>* pList
  388. )
  389. {
  390. PDNS_RPC_ZONE_LIST pZoneList = NULL;
  391. LONG status = DnssrvEnumZones(
  392. PVD_DNS_LOCAL_SERVER,
  393. ZONE_REQUEST_ALL_ZONES_AND_CACHE,
  394. NULL,
  395. &pZoneList);
  396. DNS_RPC_ZONE * pDnsZone = NULL;
  397. if( status == ERROR_SUCCESS && pZoneList )
  398. {
  399. for(DWORD i = 0; i < pZoneList->dwZoneCount; i++)
  400. {
  401. pDnsZone = (pZoneList->ZoneArray[i]);
  402. if(_wcsicmp(pDnsZone->pszZoneName, L"."))
  403. {
  404. CDomainNode objNode;
  405. objNode.wstrNodeName = pDnsZone->pszZoneName;
  406. objNode.wstrZoneName = pDnsZone->pszZoneName;
  407. pList->insert(pList->end(), objNode);
  408. }
  409. }
  410. // add catch domain
  411. CDomainNode nodeCache;
  412. nodeCache.wstrZoneName = PVD_DNS_CACHE;
  413. //add roothints
  414. CDomainNode nodeRH;
  415. nodeRH.wstrZoneName = PVD_DNS_ROOTHINTS;
  416. pList->insert(pList->begin(), nodeCache);
  417. pList->insert(pList->begin(), nodeRH);
  418. }
  419. // CLEAN UP
  420. DnssrvFreeZoneList(pZoneList);
  421. if (status != ERROR_SUCCESS)
  422. {
  423. ThrowException(status);
  424. }
  425. return WBEM_S_NO_ERROR;
  426. }
  427. SCODE
  428. CDnsWrap::ValidateServerName(
  429. const WCHAR* pwzStr)
  430. {
  431. if(_wcsicmp(pwzStr, PVD_DNS_LOCAL_SERVER))
  432. if(_wcsicmp(pwzStr, L"127.0.0.1"))
  433. if(_wcsicmp(pwzStr, m_wszpServerName) )
  434. return WBEM_E_INVALID_PARAMETER;
  435. return WBEM_S_NO_ERROR;
  436. }
  437. SCODE
  438. CDnsWrap::dnsQueryServerInfo(
  439. const WCHAR* strServerName,
  440. CWbemClassObject& NewInst,
  441. IWbemObjectSink* pHandler
  442. )
  443. {
  444. // get dnsserver
  445. DWORD dwtypeid;
  446. PVOID pdata=NULL;
  447. DNS_STATUS status;
  448. PDNS_RPC_SERVER_INFO pServerInfo = NULL;
  449. if(WBEM_S_NO_ERROR != ValidateServerName(strServerName))
  450. return WBEM_E_INVALID_PARAMETER;
  451. status = DnssrvQuery(
  452. strServerName,
  453. NULL,
  454. DNSSRV_QUERY_SERVER_INFO,
  455. &dwtypeid,
  456. &pdata);
  457. if( status == ERROR_SUCCESS)
  458. {
  459. pServerInfo = (PDNS_RPC_SERVER_INFO) pdata;
  460. NewInst.SetProperty(
  461. pServerInfo->dwVersion,
  462. PVD_SRV_VERSION);
  463. NewInst.SetProperty(
  464. pServerInfo->fDsAvailable,
  465. PVD_SRV_DS_AVAILABLE);
  466. // ListenAddress array
  467. if(pServerInfo->aipListenAddrs)
  468. {
  469. NewInst.SetProperty(
  470. pServerInfo->aipListenAddrs->AddrArray,
  471. pServerInfo->aipListenAddrs->AddrCount,
  472. MYTEXT( DNS_REGKEY_LISTEN_ADDRESSES ) );
  473. }
  474. if(pServerInfo->aipForwarders)
  475. {
  476. NewInst.SetProperty(
  477. pServerInfo->aipForwarders->AddrArray,
  478. pServerInfo->aipForwarders->AddrCount,
  479. MYTEXT( DNS_REGKEY_FORWARDERS ) );
  480. }
  481. if(pServerInfo->aipServerAddrs)
  482. {
  483. NewInst.SetProperty(
  484. pServerInfo->aipServerAddrs->AddrArray,
  485. pServerInfo->aipServerAddrs->AddrCount,
  486. PVD_SRV_SERVER_IP_ADDRESSES_ARRAY);
  487. }
  488. }
  489. DnssrvFreeServerInfo(pServerInfo);
  490. if ( status != ERROR_SUCCESS )
  491. {
  492. ThrowException(status);
  493. }
  494. return ERROR_SUCCESS;
  495. }
  496. SCODE
  497. CDnsWrap::dnsRestartServer(
  498. WCHAR* strServerName
  499. )
  500. {
  501. LONG status = DnssrvOperation(
  502. strServerName,
  503. NULL,
  504. DNSSRV_OP_RESTART,
  505. DNSSRV_TYPEID_NULL,
  506. NULL );
  507. if(status != ERROR_SUCCESS)
  508. {
  509. ThrowException(status);
  510. }
  511. return WBEM_S_NO_ERROR;
  512. }
  513. /////////////////////////////////////////////////////////////////////////////
  514. //++
  515. //
  516. // Description:
  517. // using property value from wmi instance to set dns server property
  518. //
  519. // Arguments:
  520. // Inst [IN] wmi instance whose property value
  521. // to be sent to dns server
  522. //
  523. // Return Value:
  524. // WBEM_S_NO_ERROR
  525. //
  526. //--
  527. /////////////////////////////////////////////////////////////////////////////
  528. SCODE
  529. CDnsWrap::dnsServerPropertySet(
  530. CWbemClassObject& Inst,
  531. BOOL bGet
  532. )
  533. {
  534. DBG_FN( "CDnsWrap::dnsServerPropertySet" )
  535. //
  536. // get mapping table
  537. //
  538. DWORD cNumOfEntries;
  539. PropertyTable* pt = (PropertyTable*)GetPropertyTable(&cNumOfEntries);
  540. for(int i=0; i<cNumOfEntries; i++)
  541. {
  542. FPDNSOPS fp;
  543. fp = pt[i].fpOperationSet;
  544. if(fp != NULL)
  545. {
  546. DNS_DEBUG( INSTPROV, (
  547. "%s: Inst=%p prop=%S\n", fn,
  548. &Inst,
  549. pt[i].pwzProperty ));
  550. // set dns server property
  551. fp(
  552. NULL,
  553. pt[i].pwzProperty,
  554. pt[i].OperationName,
  555. Inst);
  556. }
  557. }
  558. return S_OK;
  559. }
  560. SCODE
  561. CDnsWrap::dnsDsServerName(
  562. wstring& wstrDsName)
  563. {
  564. CServerInfo serverInfo;
  565. LPWSTR pwsz = DnssrvCreateDsServerName(
  566. (PDNS_RPC_SERVER_INFO)serverInfo.m_pInfo);
  567. if(pwsz)
  568. wstrDsName = pwsz;
  569. FREE_HEAP(pwsz);
  570. return WBEM_S_NO_ERROR;
  571. }
  572. SCODE
  573. CDnsWrap::dnsDsZoneName(
  574. wstring& wstrDsName,
  575. wstring& wstrInZone
  576. )
  577. {
  578. CServerInfo serverInfo;
  579. LPWSTR pwsz = DnssrvCreateDsZoneName(
  580. (PDNS_RPC_SERVER_INFO)serverInfo.m_pInfo,
  581. (LPWSTR)wstrInZone.data());
  582. if(pwsz)
  583. wstrDsName = pwsz;
  584. FREE_HEAP(pwsz);
  585. return WBEM_S_NO_ERROR;
  586. }
  587. SCODE
  588. CDnsWrap::dnsDsNodeName(
  589. wstring& wstrDsName,
  590. wstring& wstrInZone,
  591. wstring& wstrInNode
  592. )
  593. {
  594. CServerInfo serverInfo;
  595. LPWSTR pwsz = DnssrvCreateDsNodeName(
  596. (PDNS_RPC_SERVER_INFO)serverInfo.m_pInfo,
  597. (LPWSTR)wstrInZone.data(),
  598. (LPWSTR)wstrInNode.data());
  599. if(pwsz)
  600. wstrDsName = pwsz;
  601. FREE_HEAP(pwsz);
  602. return WBEM_S_NO_ERROR;
  603. }
  604. /////////////////////////////////////////////////////////////////////////////
  605. //++
  606. //
  607. // Description:
  608. // retrive dns server property and output to wmi instance
  609. //
  610. // Arguments:
  611. // Inst [IN OUT] wmi instance to receive property value
  612. // got from dns server
  613. //
  614. // Return Value:
  615. // WBEM_S_NO_ERROR
  616. //
  617. //--
  618. /////////////////////////////////////////////////////////////////////////////
  619. SCODE
  620. CDnsWrap::dnsServerPropertyGet(
  621. CWbemClassObject& Inst,
  622. BOOL bGet
  623. )
  624. {
  625. //
  626. // get maping table
  627. //
  628. DWORD cNumOfEntries;
  629. PropertyTable* pt = (PropertyTable*)GetPropertyTable(&cNumOfEntries);
  630. // set array and name property
  631. dnsQueryServerInfo(
  632. PVD_DNS_LOCAL_SERVER,
  633. Inst,
  634. NULL);
  635. for(int i=0; i<cNumOfEntries; i++)
  636. {
  637. FPDNSOPS fp;
  638. fp = pt[i].fpOperationGet;
  639. if(fp != NULL)
  640. { //
  641. // get property from dns, and set wmi property
  642. //
  643. fp(
  644. NULL,
  645. pt[i].pwzProperty,
  646. pt[i].OperationName,
  647. Inst);
  648. }
  649. }
  650. //
  651. // Hard-code the Status property to OK.
  652. //
  653. Inst.SetProperty( L"OK", L"Status" );
  654. return S_OK;
  655. }
  656. /*---------------------------------------------------------------------------
  657. */
  658. SCODE
  659. CDnsWrap::dnsGetDwordProperty(
  660. const char * pszZoneName,
  661. const WCHAR* wszWbemProperty,
  662. const char* pszOperationName,
  663. CWbemClassObject& Inst
  664. )
  665. {
  666. DWORD dwValue;
  667. DNS_STATUS status = DnssrvQueryDwordProperty(
  668. PVD_DNS_LOCAL_SERVER,
  669. pszZoneName,
  670. pszOperationName,
  671. &dwValue);
  672. if(status != ERROR_SUCCESS)
  673. ThrowException(status);
  674. Inst.SetProperty(
  675. dwValue,
  676. (WCHAR*)wszWbemProperty);
  677. return WBEM_S_NO_ERROR;
  678. }
  679. /*---------------------------------------------------------------------------
  680. */
  681. SCODE
  682. CDnsWrap::dnsSetDwordProperty(
  683. const char * pszZoneName,
  684. const WCHAR* wszWbemProperty,
  685. const char* pszOperationName,
  686. CWbemClassObject& Inst
  687. )
  688. {
  689. DWORD dwValue;
  690. if(Inst.GetProperty(
  691. &dwValue,
  692. (WCHAR*)wszWbemProperty) == S_OK)
  693. {
  694. DNS_RPC_NAME_AND_PARAM param;
  695. param.dwParam = dwValue;
  696. param.pszNodeName = (LPSTR) pszOperationName;
  697. DNS_STATUS status = DnssrvOperation(
  698. PVD_DNS_LOCAL_SERVER,
  699. pszZoneName,
  700. DNSSRV_OP_RESET_DWORD_PROPERTY,
  701. DNSSRV_TYPEID_NAME_AND_PARAM,
  702. & param );
  703. if(status != ERROR_SUCCESS)
  704. ThrowException(status);
  705. }
  706. return WBEM_S_NO_ERROR;
  707. }
  708. /*---------------------------------------------------------------------------
  709. */
  710. SCODE
  711. CDnsWrap::dnsGetStringProperty(
  712. const char * pszZoneName,
  713. const WCHAR * wszWbemProperty,
  714. const char * pszDnssrvPropertyName,
  715. CWbemClassObject& Inst
  716. )
  717. {
  718. DWORD dataType;
  719. PVOID pdata;
  720. DNS_STATUS status = DnssrvQuery(
  721. PVD_DNS_LOCAL_SERVER,
  722. pszZoneName,
  723. pszDnssrvPropertyName,
  724. &dataType,
  725. &pdata );
  726. if( status != ERROR_SUCCESS )
  727. {
  728. ThrowException( status );
  729. }
  730. if ( dataType != DNSSRV_TYPEID_LPWSTR )
  731. {
  732. ThrowException( WBEM_E_TYPE_MISMATCH );
  733. }
  734. Inst.SetProperty(
  735. ( PWSTR ) pdata,
  736. ( PWCHAR ) wszWbemProperty);
  737. return WBEM_S_NO_ERROR;
  738. }
  739. /*---------------------------------------------------------------------------
  740. */
  741. SCODE
  742. CDnsWrap::dnsSetStringProperty(
  743. const char * pszZoneName,
  744. const WCHAR * wszWbemProperty,
  745. const char * pszDnssrvPropertyName,
  746. CWbemClassObject & Inst
  747. )
  748. {
  749. wstring val;
  750. if( Inst.GetProperty(
  751. val,
  752. ( PWCHAR ) wszWbemProperty ) == S_OK )
  753. {
  754. DNS_STATUS status = DnssrvResetStringProperty(
  755. PVD_DNS_LOCAL_SERVER,
  756. pszZoneName,
  757. pszDnssrvPropertyName,
  758. val.c_str(),
  759. 0 );
  760. if( status != ERROR_SUCCESS )
  761. {
  762. ThrowException( status );
  763. }
  764. }
  765. return WBEM_S_NO_ERROR;
  766. } // CDnsWrap::dnsSetStringProperty
  767. /*---------------------------------------------------------------------------
  768. Read the property value from DNS server and set in class object.
  769. */
  770. SCODE
  771. CDnsWrap::dnsGetIPArrayProperty(
  772. const char * pszZoneName,
  773. const WCHAR * wszWbemProperty,
  774. const char * pszDnssrvPropertyName,
  775. CWbemClassObject & Inst
  776. )
  777. {
  778. SCODE sc = WBEM_S_NO_ERROR;
  779. DWORD dataType = 0;
  780. PVOID pdata = 0;
  781. SAFEARRAY * psa = NULL;
  782. SAFEARRAYBOUND rgsabound[ 1 ] = { 0, 0 };
  783. PIP_ARRAY pipArray;
  784. //
  785. // Retrieve the setting from the DNS server and check it's type.
  786. //
  787. DNS_STATUS status = DnssrvQuery(
  788. PVD_DNS_LOCAL_SERVER,
  789. pszZoneName,
  790. pszDnssrvPropertyName,
  791. &dataType,
  792. &pdata );
  793. if( status != ERROR_SUCCESS )
  794. {
  795. sc = status;
  796. goto Done;
  797. }
  798. if ( dataType != DNSSRV_TYPEID_IPARRAY )
  799. {
  800. sc = WBEM_E_TYPE_MISMATCH;
  801. goto Done;
  802. }
  803. if ( pdata == NULL )
  804. {
  805. Inst.SetProperty(
  806. ( PWCHAR ) NULL,
  807. ( PWCHAR ) wszWbemProperty );
  808. goto Done;
  809. }
  810. pipArray = ( PIP_ARRAY ) pdata;
  811. //
  812. // Create a SAFEARRAY of BSTRs to represent the IP address list.
  813. //
  814. rgsabound[ 0 ].cElements = pipArray->AddrCount;
  815. psa = SafeArrayCreate( VT_BSTR, 1, rgsabound );
  816. if ( psa == NULL )
  817. {
  818. sc = WBEM_E_OUT_OF_MEMORY;
  819. goto Done;
  820. }
  821. for ( int i = 0; i < pipArray->AddrCount; ++i )
  822. {
  823. BSTR bstr = AllocBstr(
  824. IpAddressToString( pipArray->AddrArray[ i ] ).c_str() );
  825. if ( bstr == NULL )
  826. {
  827. sc = WBEM_E_OUT_OF_MEMORY;
  828. goto Done;
  829. }
  830. LONG ix = i;
  831. sc = SafeArrayPutElement( psa, &ix, bstr );
  832. SysFreeString( bstr );
  833. if ( sc != S_OK )
  834. {
  835. goto Done;
  836. }
  837. }
  838. Inst.SetProperty(
  839. psa,
  840. ( PWCHAR ) wszWbemProperty );
  841. Done:
  842. if ( pdata )
  843. {
  844. // JJW: do something to free RPC piparray???
  845. }
  846. if ( psa )
  847. {
  848. SafeArrayDestroy( psa );
  849. }
  850. return sc;
  851. } // CDnsWrap::dnsGetIPArrayProperty
  852. /*---------------------------------------------------------------------------
  853. This function reads a string array property from the class object instance
  854. and builds an IP array from the values read.
  855. Caller must use FREE_HEAP to free the pIpArray.
  856. */
  857. SCODE
  858. CDnsWrap::buildIpArrayFromStringArrayProperty(
  859. CWbemClassObject & Inst,
  860. LPCWSTR wszWbemProperty,
  861. PIP_ARRAY * ppIpArray
  862. )
  863. {
  864. DBG_FN( "buildIpArrayFromStringArrayProperty" )
  865. if ( !ppIpArray )
  866. {
  867. return WBEM_E_INVALID_PARAMETER;
  868. }
  869. SCODE sc = WBEM_S_NO_ERROR;
  870. SAFEARRAY * psa = NULL;
  871. VARIANT var;
  872. PIP_ARRAY pipArray = NULL;
  873. VariantInit( &var );
  874. sc = Inst.GetProperty( &var, ( LPCWSTR ) wszWbemProperty );
  875. if( sc == S_OK && var.vt != VT_NULL )
  876. {
  877. if ( var.vt != ( VT_ARRAY |VT_BSTR ) )
  878. {
  879. sc = WBEM_E_TYPE_MISMATCH;
  880. goto Done;
  881. }
  882. sc = SafeArrayCopy( var.parray, &psa );
  883. BSTR * pbstr = NULL;
  884. sc = SafeArrayAccessData( psa, ( void ** ) &pbstr );
  885. if ( sc != S_OK )
  886. {
  887. goto Done;
  888. }
  889. int ipCount = psa->rgsabound[ 0 ].cElements;
  890. IP_ADDRESS * pipAddrArray = new IP_ADDRESS[ ipCount + 1 ];
  891. if ( pipAddrArray == NULL )
  892. {
  893. ThrowException( WBEM_E_OUT_OF_MEMORY );
  894. }
  895. for ( int i = 0; i < ipCount; ++i )
  896. {
  897. string str;
  898. WcharToString( pbstr[ i ], str );
  899. pipAddrArray[ i ] = inet_addr( str.c_str() );
  900. }
  901. SafeArrayUnaccessData( psa );
  902. pipArray = Dns_BuildIpArray( ipCount, pipAddrArray );
  903. delete [] pipAddrArray;
  904. }
  905. Done:
  906. VariantClear( &var );
  907. if ( psa )
  908. {
  909. SafeArrayDestroy( psa );
  910. }
  911. *ppIpArray = pipArray;
  912. return sc;
  913. } // CDnsWrap::buildIpArrayFromStringArrayProperty
  914. /*---------------------------------------------------------------------------
  915. Read the property value out of the class object and send to DNS server.
  916. If the specified property does not exist on the object, do nothing and
  917. return WBEM_S_NO_ERROR.
  918. */
  919. SCODE
  920. CDnsWrap::dnsSetIPArrayProperty(
  921. const char * pszZoneName,
  922. const WCHAR * wszWbemProperty,
  923. const char * pszDnssrvPropertyName,
  924. CWbemClassObject & Inst
  925. )
  926. {
  927. DBG_FN( "CDnsWrap::dnsSetIPArrayProperty" )
  928. SCODE sc = WBEM_S_NO_ERROR;
  929. PIP_ARRAY pipArray = NULL;
  930. sc = buildIpArrayFromStringArrayProperty(
  931. Inst,
  932. wszWbemProperty,
  933. &pipArray );
  934. if ( sc != WBEM_NO_ERROR )
  935. {
  936. goto Done;
  937. }
  938. DNS_STATUS status = DnssrvResetIPListProperty(
  939. PVD_DNS_LOCAL_SERVER,
  940. pszZoneName,
  941. pszDnssrvPropertyName,
  942. pipArray,
  943. 0 );
  944. FREE_HEAP( pipArray );
  945. if ( status != ERROR_SUCCESS )
  946. {
  947. sc = status;
  948. }
  949. Done:
  950. return sc;
  951. } // CDnsWrap::dnsSetIPArrayProperty
  952. SCODE
  953. CDnsWrap::dnsSetServerForwarders(
  954. const char * pszZoneName,
  955. const WCHAR* wszWbemProperty,
  956. const char* pszOperationName,
  957. CWbemClassObject & Inst
  958. )
  959. {
  960. // get forward ip array
  961. DWORD* pdwValue=NULL;
  962. DWORD dwSize;
  963. if(Inst.GetProperty(
  964. &pdwValue,
  965. &dwSize,
  966. (WCHAR*)wszWbemProperty) == S_OK)
  967. {
  968. DWORD dwSlave;
  969. DWORD dwTimeOut;
  970. try
  971. {
  972. if(Inst.GetProperty(
  973. &dwTimeOut,
  974. MYTEXT( DNS_REGKEY_FORWARD_TIMEOUT ) ) != S_OK)
  975. {
  976. return WBEM_E_INVALID_PARAMETER;
  977. }
  978. if(Inst.GetProperty(
  979. &dwSlave,
  980. MYTEXT( DNS_REGKEY_SLAVE ) ) != S_OK)
  981. {
  982. return WBEM_E_INVALID_PARAMETER;
  983. }
  984. }
  985. catch(...)
  986. {
  987. delete [] pdwValue;
  988. throw;
  989. }
  990. // now let's change it
  991. DNS_STATUS status = DnssrvResetForwarders(
  992. PVD_DNS_LOCAL_SERVER,
  993. dwSize,
  994. pdwValue,
  995. dwTimeOut,
  996. dwSlave );
  997. delete [] pdwValue;
  998. if(status != ERROR_SUCCESS)
  999. {
  1000. ThrowException(status);
  1001. }
  1002. }
  1003. return WBEM_S_NO_ERROR;
  1004. }
  1005. SCODE
  1006. CDnsWrap::dnsSetServerListenAddress(
  1007. const char * pszZoneName,
  1008. const WCHAR* wszWbemProperty,
  1009. const char* pszOperationName,
  1010. CWbemClassObject& Inst
  1011. )
  1012. {
  1013. PIP_ARRAY pipArray = NULL;
  1014. SCODE sc;
  1015. sc = buildIpArrayFromStringArrayProperty(
  1016. Inst,
  1017. wszWbemProperty,
  1018. &pipArray );
  1019. if ( sc != WBEM_NO_ERROR )
  1020. {
  1021. ThrowException( sc );
  1022. }
  1023. DNS_STATUS status = ERROR_SUCCESS;
  1024. if ( pipArray )
  1025. {
  1026. status = DnssrvResetServerListenAddresses(
  1027. PVD_DNS_LOCAL_SERVER,
  1028. pipArray->AddrCount,
  1029. pipArray->AddrArray );
  1030. }
  1031. FREE_HEAP( pipArray );
  1032. if( status != ERROR_SUCCESS)
  1033. {
  1034. ThrowException( status );
  1035. }
  1036. return WBEM_S_NO_ERROR;
  1037. } // CDnsWrap::dnsSetServerListenAddress
  1038. SCODE
  1039. CDnsWrap::dnsDeleteZone(
  1040. CObjPath& objZone)
  1041. {
  1042. wstring wstrZoneName = objZone.GetStringValueForProperty(
  1043. PVD_DOMAIN_CONTAINER_NAME
  1044. );
  1045. // dww - 6/14/99
  1046. // Added code to see if this is an integrated zone. If it is, you have to use
  1047. // The DNSSRV_OP_ZONE_DELETE_FROM_DS operation. All other zone types use the
  1048. // DNSSRV_OP_ZONE_DELETE operation.
  1049. //
  1050. // Get the Zone Type to determine if it is an integrated zone.
  1051. DWORD dwValue = -1;
  1052. LONG status = WBEM_S_NO_ERROR;
  1053. char* pszZoneName = NULL;
  1054. WcharToChar(wstrZoneName.data(), &pszZoneName);
  1055. DnssrvQueryDwordProperty(
  1056. PVD_DNS_LOCAL_SERVER,
  1057. pszZoneName,
  1058. DNS_REGKEY_ZONE_DS_INTEGRATED,
  1059. &dwValue
  1060. );
  1061. if(dwValue == 1) // integrated zone
  1062. {
  1063. status= DnssrvOperation(
  1064. PVD_DNS_LOCAL_SERVER,
  1065. pszZoneName,
  1066. DNSSRV_OP_ZONE_DELETE_FROM_DS,
  1067. DNSSRV_TYPEID_NULL,
  1068. (PVOID) NULL );
  1069. }
  1070. else
  1071. {
  1072. status= DnssrvOperation(
  1073. PVD_DNS_LOCAL_SERVER,
  1074. pszZoneName,
  1075. DNSSRV_OP_ZONE_DELETE,
  1076. DNSSRV_TYPEID_NULL,
  1077. (PVOID) NULL );
  1078. }
  1079. delete [] pszZoneName;
  1080. if( status != ERROR_SUCCESS)
  1081. ThrowException(status);
  1082. return WBEM_S_NO_ERROR;
  1083. }
  1084. wstring
  1085. CDnsWrap::GetServerName(void)
  1086. {
  1087. return m_wszpServerName;
  1088. }
  1089. SCODE
  1090. CDnsWrap::dnsGetZone(
  1091. const WCHAR* wszServer,
  1092. const WCHAR* wszZone,
  1093. CWbemClassObject& Inst,
  1094. IWbemObjectSink* pHandler
  1095. )
  1096. {
  1097. DBG_FN( "CDnsWrap::dnsGetZone" )
  1098. DNS_STATUS status;
  1099. char* pszZoneName = NULL;
  1100. PDNS_RPC_ZONE_INFO pZoneInfo=NULL;
  1101. WcharToChar(wszZone, &pszZoneName);
  1102. status = DnssrvGetZoneInfo(
  1103. wszServer,
  1104. pszZoneName,
  1105. &pZoneInfo );
  1106. DNS_DEBUG( INSTPROV, (
  1107. "%s: server %S zone %S\n", fn, wszServer, wszZone ));
  1108. DWORD dwDsIntegratedValue = 0;
  1109. if ( status == ERROR_SUCCESS)
  1110. {
  1111. status = DnssrvQueryDwordProperty(
  1112. PVD_DNS_LOCAL_SERVER,
  1113. pszZoneName,
  1114. DNS_REGKEY_ZONE_DS_INTEGRATED,
  1115. &dwDsIntegratedValue );
  1116. }
  1117. delete [] pszZoneName;
  1118. if ( status == DNS_ERROR_ZONE_DOES_NOT_EXIST)
  1119. {
  1120. return WBEM_E_NOT_FOUND;
  1121. }
  1122. // setup wbem object
  1123. if(status == ERROR_SUCCESS)
  1124. {
  1125. Inst.SetProperty(
  1126. pZoneInfo->dwZoneType,
  1127. PVD_ZONE_ZONE_TYPE);
  1128. // setup keys
  1129. Inst.SetProperty(
  1130. m_wszpServerName,
  1131. PVD_DOMAIN_SERVER_NAME);
  1132. Inst.SetProperty(
  1133. wszZone,
  1134. PVD_DOMAIN_CONTAINER_NAME);
  1135. Inst.SetProperty(
  1136. wszZone,
  1137. PVD_DOMAIN_FQDN);
  1138. Inst.SetProperty(
  1139. pZoneInfo->fAllowUpdate,
  1140. PVD_ZONE_ALLOW_UPDATE);
  1141. Inst.SetProperty(
  1142. pZoneInfo->fAutoCreated,
  1143. PVD_ZONE_AUTO_CREATED);
  1144. Inst.SetProperty(
  1145. pZoneInfo->fPaused,
  1146. PVD_ZONE_PAUSED );
  1147. Inst.SetProperty(
  1148. pZoneInfo->fReverse,
  1149. PVD_ZONE_REVERSE );
  1150. Inst.SetProperty(
  1151. pZoneInfo->fAging,
  1152. PVD_ZONE_AGING );
  1153. Inst.SetProperty(
  1154. pZoneInfo->fSecureSecondaries,
  1155. PVD_ZONE_SECURE_SECONDARIES );
  1156. Inst.SetProperty(
  1157. pZoneInfo->fNotifyLevel,
  1158. PVD_ZONE_NOTIFY);
  1159. Inst.SetProperty(
  1160. pZoneInfo->fShutdown,
  1161. PVD_ZONE_SHUTDOWN );
  1162. Inst.SetProperty(
  1163. pZoneInfo->fUseWins,
  1164. PVD_ZONE_USE_WINS);
  1165. Inst.SetProperty(
  1166. pZoneInfo->pszDataFile,
  1167. PVD_ZONE_DATA_FILE);
  1168. Inst.SetProperty(
  1169. dwDsIntegratedValue,
  1170. PVD_ZONE_DS_INTEGRATED);
  1171. Inst.SetProperty(
  1172. pZoneInfo->dwAvailForScavengeTime,
  1173. PVD_ZONE_AVAIL_FOR_SCAVENGE_TIME );
  1174. Inst.SetProperty(
  1175. pZoneInfo->dwNoRefreshInterval,
  1176. PVD_ZONE_NOREFRESH_INTERVAL );
  1177. Inst.SetProperty(
  1178. pZoneInfo->dwRefreshInterval,
  1179. PVD_ZONE_REFRESH_INTERVAL );
  1180. Inst.SetProperty(
  1181. pZoneInfo->fForwarderSlave,
  1182. PVD_ZONE_FORWARDER_SLAVE );
  1183. Inst.SetProperty(
  1184. pZoneInfo->dwForwarderTimeout,
  1185. PVD_ZONE_FORWARDER_TIMEOUT );
  1186. if (pZoneInfo->aipMasters != NULL)
  1187. {
  1188. Inst.SetProperty(
  1189. pZoneInfo->aipMasters->AddrArray,
  1190. pZoneInfo->aipMasters->AddrCount,
  1191. PVD_ZONE_MASTERS_IP_ADDRESSES_ARRAY );
  1192. }
  1193. if (pZoneInfo->aipSecondaries != NULL)
  1194. {
  1195. Inst.SetProperty(
  1196. pZoneInfo->aipSecondaries->AddrArray,
  1197. pZoneInfo->aipSecondaries->AddrCount,
  1198. PVD_ZONE_SECONDARIES_IP_ADDRESSES_ARRAY );
  1199. }
  1200. if( pZoneInfo->aipNotify != NULL)
  1201. {
  1202. Inst.SetProperty(
  1203. pZoneInfo->aipNotify->AddrArray,
  1204. pZoneInfo->aipNotify->AddrCount,
  1205. PVD_ZONE_NOTIFY_IPADDRESSES_ARRAY );
  1206. }
  1207. if( pZoneInfo->aipScavengeServers )
  1208. {
  1209. Inst.SetProperty(
  1210. pZoneInfo->aipScavengeServers->AddrArray,
  1211. pZoneInfo->aipScavengeServers->AddrCount,
  1212. PVD_ZONE_SCAVENGE_SERVERS );
  1213. }
  1214. Inst.SetProperty(
  1215. pZoneInfo->dwLastSuccessfulSoaCheck,
  1216. PVD_ZONE_LAST_SOA_CHECK );
  1217. Inst.SetProperty(
  1218. pZoneInfo->dwLastSuccessfulXfr,
  1219. PVD_ZONE_LAST_GOOD_XFR );
  1220. }
  1221. //clean up
  1222. DnssrvFreeZoneInfo(pZoneInfo);
  1223. if( status != ERROR_SUCCESS)
  1224. {
  1225. DNS_DEBUG( INSTPROV, (
  1226. "%s: server %S zone %S throwing %s\n", fn, wszServer, wszZone, status ));
  1227. ThrowException(status);
  1228. }
  1229. DNS_DEBUG( INSTPROV, (
  1230. "%s: server %S zone %S returning WBEM_S_NO_ERROR\n", fn, wszServer, wszZone ));
  1231. return WBEM_S_NO_ERROR;
  1232. }
  1233. SCODE
  1234. CDnsWrap::dnsSetProperty(
  1235. const WCHAR* wszZoneName,
  1236. const char* pszPropertyName,
  1237. DWORD dwValue
  1238. )
  1239. {
  1240. char * pszZone = NULL;
  1241. WcharToChar(wszZoneName, &pszZone);
  1242. return dnsSetProperty( pszZone, pszPropertyName, dwValue );
  1243. }
  1244. SCODE
  1245. CDnsWrap::dnsSetProperty(
  1246. const char* pszZoneName,
  1247. const char* pszPropertyName,
  1248. DWORD dwValue
  1249. )
  1250. {
  1251. DBG_FN( "CDnsWrap::dnsSetDwordProperty" );
  1252. DNS_DEBUG( INSTPROV, (
  1253. "%s: zone %s property %s value %d\n", fn,
  1254. pszZoneName,
  1255. pszPropertyName,
  1256. dwValue ));
  1257. LONG status = DnssrvResetDwordProperty(
  1258. PVD_DNS_LOCAL_SERVER,
  1259. pszZoneName,
  1260. pszPropertyName,
  1261. dwValue );
  1262. if ( status != ERROR_SUCCESS )
  1263. {
  1264. DNS_DEBUG( INSTPROV, (
  1265. "%s: throwing 0x%X for zone %s property %s\n", fn,
  1266. status,
  1267. pszZoneName,
  1268. pszPropertyName ));
  1269. ThrowException( status );
  1270. }
  1271. return WBEM_S_NO_ERROR;
  1272. }
  1273. SCODE
  1274. CDnsWrap::dnsQueryProperty(
  1275. const WCHAR* wszZoneName,
  1276. const WCHAR* wszPropertyName,
  1277. DWORD* pdwResult
  1278. )
  1279. {
  1280. char * szZone = NULL;
  1281. char * szProp = NULL;
  1282. WcharToChar(wszZoneName, &szZone);
  1283. WcharToChar(wszPropertyName, &szProp);
  1284. LONG status = DnssrvQueryZoneDwordProperty(
  1285. PVD_DNS_LOCAL_SERVER,
  1286. szZone,
  1287. szProp,
  1288. pdwResult
  1289. );
  1290. delete [] szZone;
  1291. delete [] szProp;
  1292. if(status != ERROR_SUCCESS)
  1293. ThrowException(status);
  1294. return WBEM_S_NO_ERROR;
  1295. }
  1296. SCODE
  1297. CDnsWrap::dnsResumeZone(
  1298. const char* strZoneName
  1299. )
  1300. {
  1301. DNS_STATUS status = DnssrvResumeZone(
  1302. PVD_DNS_LOCAL_SERVER,
  1303. strZoneName);
  1304. if(status != ERROR_SUCCESS)
  1305. {
  1306. ThrowException(status);
  1307. }
  1308. return WBEM_S_NO_ERROR;
  1309. }
  1310. SCODE
  1311. CDnsWrap::dnsPauseZone(
  1312. const char *strZoneName
  1313. )
  1314. {
  1315. int status = DnssrvPauseZone(
  1316. PVD_DNS_LOCAL_SERVER,
  1317. strZoneName // zone name
  1318. );
  1319. if ( status != ERROR_SUCCESS )
  1320. {
  1321. ThrowException(status);
  1322. }
  1323. return WBEM_S_NO_ERROR;
  1324. }
  1325. void
  1326. CDnsWrap::ThrowException(
  1327. LONG status)
  1328. {
  1329. CDnsProvException dnsExcep(Dns_StatusString(status),status);
  1330. throw dnsExcep;
  1331. }
  1332. void
  1333. CDnsWrap::ThrowException(
  1334. LPCSTR ErrString
  1335. )
  1336. {
  1337. CDnsProvException dnsExcep(ErrString);
  1338. throw dnsExcep;
  1339. }
  1340. SCODE CDnsWrap::dnsClearCache()
  1341. {
  1342. DNS_STATUS status = DnssrvOperation(
  1343. PVD_DNS_LOCAL_SERVER,
  1344. NULL,
  1345. DNSSRV_OP_CLEAR_CACHE,
  1346. DNSSRV_TYPEID_NULL,
  1347. NULL );
  1348. if(status != S_OK)
  1349. ThrowException(status);
  1350. return WBEM_S_NO_ERROR;
  1351. }
  1352. SCODE CDnsWrap::dnsAgeAllRecords(
  1353. const char * pszZoneName,
  1354. const char * pszNodeName,
  1355. BOOL bAgeSubtree
  1356. )
  1357. {
  1358. DBG_FN( "CDnsWrap::dnsAgeAllRecords" );
  1359. DNS_RPC_NAME_AND_PARAM param;
  1360. param.dwParam = ( DWORD ) bAgeSubtree;
  1361. param.pszNodeName = ( LPSTR ) pszNodeName;
  1362. DNS_DEBUG( INSTPROV, (
  1363. "%s: zone: %s node %s subtree %d\n", fn,
  1364. pszZoneName,
  1365. pszNodeName,
  1366. bAgeSubtree ));
  1367. DNS_STATUS status = DnssrvOperation(
  1368. PVD_DNS_LOCAL_SERVER,
  1369. pszZoneName,
  1370. DNSSRV_OP_FORCE_AGING_ON_NODE,
  1371. DNSSRV_TYPEID_NAME_AND_PARAM,
  1372. ( PVOID ) &param );
  1373. if ( status != S_OK )
  1374. {
  1375. ThrowException( status );
  1376. }
  1377. return WBEM_S_NO_ERROR;
  1378. } // CDnsWrap::dnsAgeAllRecords
  1379. SCODE
  1380. CDnsWrap::dnsOperation(
  1381. string& strZone, //zone name
  1382. OpsFlag OperationID
  1383. )
  1384. {
  1385. string strOps;
  1386. switch ( OperationID )
  1387. {
  1388. case DNS_WRAP_RELOAD_ZONE:
  1389. strOps = DNSSRV_OP_ZONE_RELOAD;
  1390. break;
  1391. case DNS_WRAP_RESUME_ZONE:
  1392. strOps = DNSSRV_OP_ZONE_RESUME;
  1393. break;
  1394. case DNS_WRAP_PAUSE_ZONE:
  1395. strOps = DNSSRV_OP_ZONE_PAUSE;
  1396. break;
  1397. case DNS_WRAP_DS_UPDATE:
  1398. strOps = DNSSRV_OP_ZONE_UPDATE_FROM_DS;
  1399. break;
  1400. case DNS_WRAP_WRITE_BACK_ZONE:
  1401. strOps = DNSSRV_OP_ZONE_WRITE_BACK_FILE;
  1402. break;
  1403. case DNS_WRAP_REFRESH_SECONDARY:
  1404. strOps = DNSSRV_OP_ZONE_REFRESH;
  1405. break;
  1406. default:
  1407. return WBEM_E_FAILED;
  1408. }
  1409. DNS_STATUS status = DnssrvOperation(
  1410. PVD_DNS_LOCAL_SERVER,
  1411. strZone.data(),
  1412. strOps.data(),
  1413. DNSSRV_TYPEID_NULL,
  1414. NULL );
  1415. if ( status != S_OK )
  1416. {
  1417. ThrowException( status );
  1418. }
  1419. return WBEM_S_NO_ERROR;
  1420. } // CDnsWrap::dnsOperation
  1421. /////////////////////////////////////////////////////////////////////////////
  1422. //++
  1423. //
  1424. // Description:
  1425. // returns a mapping table that maps wbem property and dns property
  1426. // , and operation can be performed
  1427. // on the property such as get and set
  1428. //
  1429. // Arguments:
  1430. // pdwSize [IN ] size of the table
  1431. // Return Value:
  1432. // WBEM_S_NO_ERROR
  1433. //
  1434. //--
  1435. /////////////////////////////////////////////////////////////////////////////
  1436. PVOID
  1437. CDnsWrap::GetPropertyTable(
  1438. DWORD* pdwSize
  1439. )
  1440. {
  1441. //
  1442. // Macros to simplify adding elements to the property array.
  1443. //
  1444. #define DECLARE_DW_ELEMENT( str ) \
  1445. { \
  1446. MYTEXT( str ), \
  1447. str, \
  1448. dnsSetDwordProperty, \
  1449. dnsGetDwordProperty \
  1450. }
  1451. #define DECLARE_STR_ELEMENT( str ) \
  1452. { \
  1453. MYTEXT( str ), \
  1454. str, \
  1455. dnsSetStringProperty, \
  1456. dnsGetStringProperty \
  1457. }
  1458. #define DECLARE_IPARRAY_ELEMENT( str ) \
  1459. { \
  1460. MYTEXT( str ), \
  1461. str, \
  1462. dnsSetIPArrayProperty, \
  1463. dnsGetIPArrayProperty \
  1464. }
  1465. //
  1466. // Array of server properties.
  1467. //
  1468. static PropertyTable pt[] =
  1469. {
  1470. DECLARE_DW_ELEMENT( DNS_REGKEY_ADDRESS_ANSWER_LIMIT ),
  1471. DECLARE_DW_ELEMENT( DNS_REGKEY_ALLOW_UPDATE ),
  1472. DECLARE_DW_ELEMENT( DNS_REGKEY_RPC_PROTOCOL ),
  1473. DECLARE_DW_ELEMENT( DNS_REGKEY_NO_RECURSION ),
  1474. DECLARE_DW_ELEMENT( DNS_REGKEY_RECURSION_RETRY ),
  1475. DECLARE_DW_ELEMENT( DNS_REGKEY_RECURSION_TIMEOUT ),
  1476. DECLARE_DW_ELEMENT( DNS_REGKEY_FORWARD_TIMEOUT ),
  1477. DECLARE_DW_ELEMENT( DNS_REGKEY_SLAVE ),
  1478. DECLARE_DW_ELEMENT( DNS_REGKEY_AUTO_CACHE_UPDATE ),
  1479. DECLARE_DW_ELEMENT( DNS_REGKEY_DISJOINT_NETS ),
  1480. DECLARE_DW_ELEMENT( DNS_REGKEY_ROUND_ROBIN ),
  1481. DECLARE_DW_ELEMENT( DNS_REGKEY_BIND_SECONDARIES ),
  1482. DECLARE_DW_ELEMENT( DNS_REGKEY_WRITE_AUTHORITY_NS ),
  1483. DECLARE_DW_ELEMENT( DNS_REGKEY_STRICT_FILE_PARSING ),
  1484. DECLARE_DW_ELEMENT( DNS_REGKEY_LOOSE_WILDCARDING ),
  1485. DECLARE_DW_ELEMENT( DNS_REGKEY_EVENTLOG_LEVEL ),
  1486. DECLARE_DW_ELEMENT( DNS_REGKEY_LOG_LEVEL ),
  1487. DECLARE_DW_ELEMENT( DNS_REGKEY_MAX_CACHE_TTL ),
  1488. DECLARE_DW_ELEMENT( DNS_REGKEY_MAX_NEGATIVE_CACHE_TTL ),
  1489. DECLARE_DW_ELEMENT( DNS_REGKEY_DS_POLLING_INTERVAL ),
  1490. DECLARE_DW_ELEMENT( DNS_REGKEY_DS_TOMBSTONE_INTERVAL ),
  1491. DECLARE_DW_ELEMENT( DNS_REGKEY_NAME_CHECK_FLAG ),
  1492. DECLARE_DW_ELEMENT( DNS_REGKEY_SEND_PORT ),
  1493. DECLARE_DW_ELEMENT( DNS_REGKEY_BOOT_METHOD ),
  1494. DECLARE_DW_ELEMENT( DNS_REGKEY_NO_AUTO_REVERSE_ZONES ),
  1495. DECLARE_DW_ELEMENT( DNS_REGKEY_LOCAL_NET_PRIORITY ),
  1496. DECLARE_DW_ELEMENT( DNS_REGKEY_FORWARD_DELEGATIONS ),
  1497. DECLARE_DW_ELEMENT( DNS_REGKEY_SECURE_RESPONSES ),
  1498. DECLARE_DW_ELEMENT( DNS_REGKEY_AUTO_CONFIG_FILE_ZONES ),
  1499. DECLARE_DW_ELEMENT( DNS_REGKEY_DEFAULT_AGING_STATE ),
  1500. DECLARE_DW_ELEMENT( DNS_REGKEY_DEFAULT_REFRESH_INTERVAL ),
  1501. DECLARE_DW_ELEMENT( DNS_REGKEY_DEFAULT_NOREFRESH_INTERVAL ),
  1502. DECLARE_DW_ELEMENT( DNS_REGKEY_ENABLE_DNSSEC ),
  1503. DECLARE_DW_ELEMENT( DNS_REGKEY_ENABLE_EDNS ),
  1504. DECLARE_DW_ELEMENT( DNS_REGKEY_EDNS_CACHE_TIMEOUT ),
  1505. DECLARE_DW_ELEMENT( DNS_REGKEY_ENABLE_DP ),
  1506. DECLARE_DW_ELEMENT( DNS_REGKEY_XFR_CONNECT_TIMEOUT ),
  1507. DECLARE_DW_ELEMENT( DNS_REGKEY_SCAVENGING_INTERVAL ),
  1508. DECLARE_DW_ELEMENT( DNS_REGKEY_UPDATE_OPTIONS ),
  1509. DECLARE_DW_ELEMENT( DNS_REGKEY_LOG_FILE_MAX_SIZE ),
  1510. DECLARE_STR_ELEMENT( DNS_REGKEY_LOG_FILE_PATH ),
  1511. DECLARE_IPARRAY_ELEMENT( DNS_REGKEY_LOG_IP_FILTER_LIST ),
  1512. {
  1513. MYTEXT( DNS_REGKEY_FORWARDERS ),
  1514. DNS_REGKEY_FORWARDERS,
  1515. dnsSetServerForwarders,
  1516. NULL
  1517. },
  1518. DECLARE_DW_ELEMENT( DNS_REGKEY_FORWARD_TIMEOUT ),
  1519. DECLARE_DW_ELEMENT( DNS_REGKEY_SLAVE ),
  1520. {
  1521. MYTEXT( DNS_REGKEY_LISTEN_ADDRESSES ),
  1522. DNS_REGKEY_LISTEN_ADDRESSES,
  1523. dnsSetServerListenAddress,
  1524. NULL
  1525. },
  1526. };
  1527. static DWORD dwNumofElements =
  1528. sizeof(pt)/sizeof(PropertyTable);
  1529. *pdwSize = dwNumofElements;
  1530. return &pt;
  1531. }
  1532. SCODE
  1533. CDnsWrap::dnsZoneCreate(
  1534. string & strZoneName,
  1535. DWORD dwZoneType,
  1536. BOOL DsIntegrated,
  1537. string & strDataFile,
  1538. string & strAdmin,
  1539. DWORD * pIp,
  1540. DWORD cIp
  1541. )
  1542. {
  1543. DWORD loadOptions = 0;
  1544. LPSTR pszData = NULL;
  1545. //
  1546. // Pre-processing by zone type. Convert WMI zone type to RPC zone type
  1547. // by incremented by one: WMI type 0 is primary but RPC types start
  1548. // at cache.
  1549. //
  1550. ++dwZoneType;
  1551. if( dwZoneType == DNS_ZONE_TYPE_SECONDARY )
  1552. {
  1553. // secondary zone must supply master ip array
  1554. if ( cIp <=0 || pIp == NULL )
  1555. {
  1556. return WBEM_E_INVALID_PARAMETER;
  1557. }
  1558. }
  1559. if( !strDataFile.empty())
  1560. {
  1561. loadOptions |= DNS_ZONE_LOAD_EXISTING;
  1562. pszData = (LPSTR) strDataFile.data();
  1563. }
  1564. string strAdminEmail = strAdmin;
  1565. if ( strAdminEmail.empty() )
  1566. {
  1567. strAdminEmail = "Admin";
  1568. }
  1569. DNS_STATUS status;
  1570. status = DnssrvCreateZone(
  1571. PVD_DNS_LOCAL_SERVER, // server
  1572. (char*) strZoneName.data(), // zone name
  1573. dwZoneType, // zone type
  1574. strAdminEmail.data(), // admin email
  1575. cIp, // size of master
  1576. pIp, // master ips
  1577. loadOptions, // load options
  1578. DsIntegrated, // DS integrated
  1579. pszData, // data file name
  1580. 0, // timeout for forwarder zone
  1581. 0 ); // slave flag for forwarder zone
  1582. if ( status != ERROR_SUCCESS )
  1583. {
  1584. ThrowException( status );
  1585. }
  1586. return WBEM_S_NO_ERROR;
  1587. } // CDnsWrap::dnsZoneCreate
  1588. SCODE
  1589. CDnsWrap::dnsZoneChangeType(
  1590. string & strZone,
  1591. DWORD dwZoneType,
  1592. BOOL DsIntegrated,
  1593. string & strDataFile,
  1594. string & strAdmin,
  1595. DWORD * pIp,
  1596. DWORD cIp
  1597. )
  1598. {
  1599. DWORD dwLoadOptions = TRUE;
  1600. DWORD cMaster = 0;
  1601. //
  1602. // Convert WMI zone type to RPC zone type by incrementing by one.
  1603. //
  1604. ++dwZoneType;
  1605. //
  1606. // Examine parameters.
  1607. //
  1608. if ( dwZoneType == DNS_ZONE_TYPE_PRIMARY )
  1609. {
  1610. if ( DsIntegrated && !strDataFile.empty() ||
  1611. !DsIntegrated && strDataFile.empty() )
  1612. {
  1613. return WBEM_E_INVALID_PARAMETER;
  1614. }
  1615. }
  1616. else if ( dwZoneType == DNS_ZONE_TYPE_SECONDARY )
  1617. {
  1618. if ( pIp == NULL || cIp <= 0 )
  1619. {
  1620. // secondary must have master IP
  1621. return WBEM_E_INVALID_PARAMETER;
  1622. }
  1623. }
  1624. //
  1625. // Change zone type.
  1626. //
  1627. DNS_STATUS status;
  1628. status = DnssrvResetZoneTypeEx(
  1629. PVD_DNS_LOCAL_SERVER,
  1630. strZone.data(),
  1631. dwZoneType,
  1632. cIp,
  1633. pIp,
  1634. dwLoadOptions,
  1635. DsIntegrated,
  1636. strDataFile.data(),
  1637. 0, // dwDpFlags
  1638. NULL ); // pszDpFqdn
  1639. if ( status != S_OK )
  1640. {
  1641. ThrowException( status);
  1642. }
  1643. return WBEM_S_NO_ERROR;
  1644. } // CDnsWrap::dnsZoneChangeType
  1645. SCODE
  1646. CDnsWrap::dnsZoneResetSecondary(
  1647. string& strZoneName,
  1648. DWORD dwSecurity,
  1649. DWORD* pSecondaryIp,
  1650. DWORD cSecondaryIp,
  1651. DWORD dwNotify,
  1652. DWORD * pNotifyIp,
  1653. DWORD cNotifyIp
  1654. )
  1655. {
  1656. DNS_STATUS status;
  1657. DWORD tdwNotifyLevel = ZONE_NOTIFY_ALL;
  1658. DWORD tdwSecurity = ZONE_SECSECURE_NO_SECURITY;
  1659. if( dwSecurity <=3 )
  1660. {
  1661. tdwSecurity = dwSecurity;
  1662. }
  1663. if( dwNotify <=2)
  1664. {
  1665. tdwNotifyLevel = dwNotify;
  1666. }
  1667. status = DnssrvResetZoneSecondaries(
  1668. PVD_DNS_LOCAL_SERVER,
  1669. strZoneName.data(),
  1670. tdwSecurity,
  1671. cSecondaryIp,
  1672. pSecondaryIp,
  1673. tdwNotifyLevel,
  1674. cNotifyIp,
  1675. pNotifyIp);
  1676. if ( status != ERROR_SUCCESS )
  1677. {
  1678. ThrowException(status);
  1679. }
  1680. return WBEM_S_NO_ERROR;
  1681. }
  1682. SCODE
  1683. CDnsWrap::dnsZoneResetMaster(
  1684. string& strZoneName,
  1685. DWORD* pMasterIp,
  1686. DWORD cMasterIp,
  1687. DWORD dwLocal
  1688. )
  1689. {
  1690. DNS_STATUS status;
  1691. DWORD dwValue = -1;
  1692. status = DnssrvResetZoneMastersEx(
  1693. PVD_DNS_LOCAL_SERVER,
  1694. strZoneName.data(),
  1695. cMasterIp,
  1696. pMasterIp,
  1697. dwLocal );
  1698. if ( status != ERROR_SUCCESS )
  1699. {
  1700. ThrowException(status);
  1701. }
  1702. return WBEM_S_NO_ERROR;
  1703. }
  1704. SCODE
  1705. CDnsWrap::dnsZonePut(
  1706. CWbemClassObject& Inst
  1707. )
  1708. /*++
  1709. Routine Description:
  1710. This function commits all of the property values in a zone
  1711. object to the DNS server.
  1712. Arguments:
  1713. Inst -- zone object
  1714. Return Value:
  1715. S_OK on success.
  1716. --*/
  1717. {
  1718. DBG_FN( "CDnsWrap::dnsZonePut" )
  1719. SCODE sc;
  1720. DNS_STATUS status = ERROR_SUCCESS;
  1721. DWORD dwProperty = 0;
  1722. DWORD dwZoneType = -1;
  1723. DWORD * dwArray = NULL;
  1724. DWORD dwArraySize = 0;
  1725. string strZoneName;
  1726. string strDataFile;
  1727. DWORD dwValue;
  1728. //
  1729. // Setting some properties, such as ScavengeServers on a zone where
  1730. // aging is not enabled, will result in DNS_ERROR_INVALID_ZONE_TYPE.
  1731. // I do not want to duplicate all of these rules in the WMI provider,
  1732. // so if the server returns DNS_ERROR_INVALID_ZONE_TYPE the WMI
  1733. // provider will assume everything is okay and continue.
  1734. //
  1735. #define DNS_CHECK_STATUS() \
  1736. if ( status == DNS_ERROR_INVALID_ZONE_TYPE ) \
  1737. status = ERROR_SUCCESS; \
  1738. else if ( status != ERROR_SUCCESS ) goto Done
  1739. //
  1740. // Get basic properties of the new zone.
  1741. //
  1742. Inst.GetProperty( strZoneName, PVD_DOMAIN_CONTAINER_NAME );
  1743. Inst.GetProperty( &dwZoneType, PVD_ZONE_ZONE_TYPE );
  1744. DNS_DEBUG( INSTPROV, (
  1745. "%s: zone %s\n", fn, strZoneName.c_str() ));
  1746. //
  1747. // Retrieve properties from the class object and set values
  1748. // to the server.
  1749. //
  1750. if( dwZoneType == DNS_ZONE_TYPE_PRIMARY &&
  1751. Inst.GetProperty(
  1752. &dwProperty,
  1753. PVD_ZONE_ALLOW_UPDATE ) == S_OK )
  1754. {
  1755. status = dnsSetProperty(
  1756. strZoneName.data(),
  1757. DNS_REGKEY_ZONE_ALLOW_UPDATE,
  1758. dwProperty );
  1759. DNS_CHECK_STATUS();
  1760. }
  1761. if( Inst.GetProperty(
  1762. &dwProperty,
  1763. PVD_ZONE_REFRESH_INTERVAL ) == S_OK )
  1764. {
  1765. status = dnsSetProperty(
  1766. strZoneName.data(),
  1767. DNS_REGKEY_ZONE_REFRESH_INTERVAL,
  1768. dwProperty );
  1769. DNS_CHECK_STATUS();
  1770. }
  1771. if( Inst.GetProperty(
  1772. &dwProperty,
  1773. PVD_ZONE_NOREFRESH_INTERVAL ) == S_OK )
  1774. {
  1775. status = dnsSetProperty(
  1776. strZoneName.data(),
  1777. DNS_REGKEY_ZONE_NOREFRESH_INTERVAL,
  1778. dwProperty );
  1779. DNS_CHECK_STATUS();
  1780. }
  1781. if ( dwZoneType == DNS_ZONE_TYPE_SECONDARY
  1782. || dwZoneType == DNS_ZONE_TYPE_STUB
  1783. || dwZoneType == DNS_ZONE_TYPE_FORWARDER )
  1784. {
  1785. status = dnsSetIPArrayProperty(
  1786. strZoneName.data(),
  1787. MYTEXT( DNS_REGKEY_ZONE_MASTERS ),
  1788. DNS_REGKEY_ZONE_MASTERS,
  1789. Inst );
  1790. DNS_CHECK_STATUS();
  1791. status = dnsSetIPArrayProperty(
  1792. strZoneName.data(),
  1793. MYTEXT( DNS_REGKEY_ZONE_LOCAL_MASTERS ),
  1794. DNS_REGKEY_ZONE_LOCAL_MASTERS,
  1795. Inst );
  1796. DNS_CHECK_STATUS();
  1797. }
  1798. status = dnsSetIPArrayProperty(
  1799. strZoneName.data(),
  1800. MYTEXT( DNS_REGKEY_ZONE_SCAVENGE_SERVERS ),
  1801. DNS_REGKEY_ZONE_SCAVENGE_SERVERS,
  1802. Inst );
  1803. DNS_CHECK_STATUS();
  1804. //
  1805. // Forwarder zone properties.
  1806. //
  1807. if ( dwZoneType == DNS_ZONE_TYPE_FORWARDER )
  1808. {
  1809. if( Inst.GetProperty(
  1810. &dwProperty,
  1811. MYTEXT( DNS_REGKEY_ZONE_FWD_SLAVE ) ) == S_OK )
  1812. {
  1813. status = dnsSetProperty(
  1814. strZoneName.data(),
  1815. DNS_REGKEY_ZONE_FWD_SLAVE,
  1816. dwProperty );
  1817. DNS_CHECK_STATUS();
  1818. }
  1819. if( Inst.GetProperty(
  1820. &dwProperty,
  1821. MYTEXT( DNS_REGKEY_ZONE_FWD_TIMEOUT ) ) == S_OK )
  1822. {
  1823. status = dnsSetProperty(
  1824. strZoneName.data(),
  1825. DNS_REGKEY_ZONE_FWD_TIMEOUT,
  1826. dwProperty );
  1827. DNS_CHECK_STATUS();
  1828. }
  1829. }
  1830. //
  1831. // To handle the zone data file, call DnssrvResetZoneDatabase
  1832. //
  1833. dwValue = 0;
  1834. DnssrvQueryDwordProperty(
  1835. PVD_DNS_LOCAL_SERVER,
  1836. strZoneName.data(),
  1837. DNS_REGKEY_ZONE_DS_INTEGRATED,
  1838. &dwValue );
  1839. if( Inst.GetProperty(
  1840. strDataFile,
  1841. PVD_ZONE_DATA_FILE ) == S_OK )
  1842. {
  1843. if( status == S_OK && dwZoneType != 0 && !strDataFile.empty() )
  1844. {
  1845. status = DnssrvResetZoneDatabase(
  1846. PVD_DNS_LOCAL_SERVER,
  1847. strZoneName.data(),
  1848. dwValue,
  1849. strDataFile.data() );
  1850. DNS_CHECK_STATUS();
  1851. }
  1852. }
  1853. Done:
  1854. if ( status != ERROR_SUCCESS )
  1855. {
  1856. DNS_DEBUG( INSTPROV, (
  1857. "%s: zone %s throwing %d\n", fn, strZoneName.c_str(), status ));
  1858. ThrowException( status );
  1859. }
  1860. DNS_DEBUG( INSTPROV, (
  1861. "%s: zone %s returning WBEM_S_NO_ERROR\n", fn, strZoneName.c_str() ));
  1862. return WBEM_S_NO_ERROR;
  1863. #undef DNS_CHECK_STATUS
  1864. }
  1865. static SCODE
  1866. dnsWrapCreateStatistic(
  1867. IWbemClassObject * pClass,
  1868. IWbemObjectSink * pHandler,
  1869. DWORD dwStatCollection,
  1870. const WCHAR * pszStatisticName,
  1871. CIMTYPE cimType,
  1872. const void * value
  1873. )
  1874. /*++
  1875. Routine Description:
  1876. Creates and populates a single DNS statistic object.
  1877. Arguments:
  1878. pClass -- MicrosoftDNS_Statistic class object used to spawn new instance
  1879. dwStatCollection -- index into global collection array
  1880. pszStatisticName -- statistic name
  1881. cimType - type of statistic
  1882. VT_UI4: value is a DWORD
  1883. VT_BSTR: value is a pointer to a string
  1884. value - interpret as per cimType
  1885. Return Value:
  1886. S_OK or error code.
  1887. --*/
  1888. {
  1889. CDnsWrap & dns = CDnsWrap::DnsObject();
  1890. CWbemClassObject Inst;
  1891. pClass->SpawnInstance( 0, &Inst);
  1892. Inst.SetProperty( dns.GetServerName(), PVD_DOMAIN_SERVER_NAME );
  1893. Inst.SetProperty( g_StatInfo[ dwStatCollection ].pszName, L"CollectionName" );
  1894. Inst.SetProperty( g_StatInfo[ dwStatCollection ].dwStatId, L"CollectionId" );
  1895. Inst.SetProperty( pszStatisticName, L"Name" );
  1896. if ( cimType == VT_BSTR )
  1897. {
  1898. Inst.SetProperty( ( LPCWSTR ) value, L"StringValue" );
  1899. }
  1900. else
  1901. {
  1902. DWORD dw = ( DWORD ) ( DWORD_PTR ) value;
  1903. Inst.SetProperty( dw, L"Value" );
  1904. }
  1905. pHandler->Indicate( 1, &Inst );
  1906. return S_OK;
  1907. } // dnsWrapCreateStatistic
  1908. static SCODE
  1909. dnsWrapAddStatisticsForTypeArray(
  1910. IWbemClassObject * pClass,
  1911. IWbemObjectSink * pHandler,
  1912. DWORD statCollIdx,
  1913. PWSTR pszHeader,
  1914. PDWORD pArray
  1915. )
  1916. /*++
  1917. Routine Description:
  1918. Adds DWORD statistics for each member of a type array.
  1919. Arguments:
  1920. pClass -- WMI statistic class
  1921. pHandler -- WMI object sink
  1922. statCollIdx -- index into global stat information array
  1923. pszHeader -- header text used to format statistic description
  1924. pArray -- array of DWORDs for types
  1925. Return Value:
  1926. None
  1927. --*/
  1928. {
  1929. WCHAR sz[ 80 ];
  1930. #define dwStat( pwszName, dwValue ) \
  1931. dnsWrapCreateStatistic( \
  1932. pClass, \
  1933. pHandler, \
  1934. statCollIdx, \
  1935. pwszName, \
  1936. VT_UI4, \
  1937. ( void * ) ( DWORD_PTR ) ( dwValue ) );
  1938. for ( DWORD i = 0; i < STATS_TYPE_MAX; i++ )
  1939. {
  1940. if ( i == STATS_TYPE_MIXED || i == STATS_TYPE_UNKNOWN )
  1941. {
  1942. continue;
  1943. }
  1944. wsprintfW(
  1945. sz,
  1946. L"%s for %S type",
  1947. pszHeader,
  1948. Dns_RecordStringForType( ( WORD ) i ) );
  1949. dwStat( sz, pArray[ i ] );
  1950. }
  1951. wsprintfW(
  1952. sz,
  1953. L"%s for unknown type",
  1954. pszHeader );
  1955. dwStat( sz, pArray[ STATS_TYPE_UNKNOWN ] );
  1956. wsprintfW(
  1957. sz,
  1958. L"%s for mixed type",
  1959. pszHeader );
  1960. dwStat( sz, pArray[ STATS_TYPE_MIXED ] );
  1961. #undef dwStat
  1962. return S_OK;
  1963. } // dnsWrapAddStatisticsForTypeArray
  1964. static SCODE
  1965. dnsWrapHandleSingleStat(
  1966. IWbemClassObject * pClass,
  1967. IWbemObjectSink * pHandler,
  1968. PDNSSRV_STAT pStat
  1969. )
  1970. /*++
  1971. Routine Description:
  1972. Process a single statistic buffer by creating Statistic object
  1973. instances for each of the members of the stat buffer.
  1974. Arguments:
  1975. pClass -- WMI statistic class
  1976. pHandler -- WMI object sink
  1977. pStat -- buffer of stats to process
  1978. Return Value:
  1979. None
  1980. --*/
  1981. {
  1982. SCODE sc = S_OK;
  1983. const int szBufferLen = 254;
  1984. WCHAR szBuffer[ szBufferLen ];
  1985. SAFEARRAY * psa = NULL;
  1986. SAFEARRAYBOUND rgsabound[ 1 ] = { 0, 0 };
  1987. int statCollIdx = -1;
  1988. //
  1989. // Get index into g_StatInfo element for this stat.
  1990. //
  1991. for ( int i = 0;
  1992. g_StatInfo[ i ].dwStatId != 0 &&
  1993. g_StatInfo[ i ].dwStatId != pStat->Header.StatId;
  1994. ++i );
  1995. if ( g_StatInfo[ i ].dwStatId != 0 )
  1996. {
  1997. statCollIdx = i;
  1998. }
  1999. //
  2000. // Macros to creating individual stat objects.
  2001. //
  2002. #define strStat( pwszName, pwszValue ) \
  2003. dnsWrapCreateStatistic( \
  2004. pClass, \
  2005. pHandler, \
  2006. statCollIdx, \
  2007. pwszName, \
  2008. VT_BSTR, \
  2009. pwszValue );
  2010. #define dwStat( pwszName, dwValue ) \
  2011. dnsWrapCreateStatistic( \
  2012. pClass, \
  2013. pHandler, \
  2014. statCollIdx, \
  2015. pwszName, \
  2016. VT_UI4, \
  2017. ( void * ) ( DWORD_PTR ) ( dwValue ) );
  2018. //
  2019. // Process the individual statistics in this stat collection.
  2020. //
  2021. switch ( pStat->Header.StatId )
  2022. {
  2023. case DNSSRV_STATID_TIME:
  2024. {
  2025. PDNSSRV_TIME_STATS pstat = ( PDNSSRV_TIME_STATS ) pStat;
  2026. SYSTEMTIME localTime;
  2027. SystemTimeToTzSpecificLocalTime(
  2028. NULL,
  2029. ( PSYSTEMTIME ) &pstat->ServerStartTime,
  2030. &localTime );
  2031. GetDateFormatW(
  2032. LOCALE_SYSTEM_DEFAULT,
  2033. LOCALE_NOUSEROVERRIDE,
  2034. &localTime,
  2035. NULL,
  2036. szBuffer,
  2037. szBufferLen );
  2038. wcscat( szBuffer, L" " );
  2039. GetTimeFormatW(
  2040. LOCALE_SYSTEM_DEFAULT,
  2041. LOCALE_NOUSEROVERRIDE,
  2042. &localTime,
  2043. NULL,
  2044. szBuffer + wcslen( szBuffer ),
  2045. szBufferLen - wcslen( szBuffer ) );
  2046. strStat( L"Server started", szBuffer );
  2047. SystemTimeToTzSpecificLocalTime(
  2048. NULL,
  2049. ( PSYSTEMTIME ) &pstat->LastClearTime,
  2050. &localTime );
  2051. GetDateFormatW(
  2052. LOCALE_SYSTEM_DEFAULT,
  2053. LOCALE_NOUSEROVERRIDE,
  2054. &localTime,
  2055. NULL,
  2056. szBuffer,
  2057. szBufferLen );
  2058. wcscat( szBuffer, L" " );
  2059. GetTimeFormatW(
  2060. LOCALE_SYSTEM_DEFAULT,
  2061. LOCALE_NOUSEROVERRIDE,
  2062. &localTime,
  2063. NULL,
  2064. szBuffer + wcslen( szBuffer ),
  2065. szBufferLen - wcslen( szBuffer ) );
  2066. strStat( L"Statistics last cleared", szBuffer );
  2067. dwStat( L"Seconds since start", pstat->SecondsSinceServerStart );
  2068. dwStat( L"Seconds since statistics cleared", pstat->SecondsSinceLastClear );
  2069. break;
  2070. }
  2071. case DNSSRV_STATID_QUERY:
  2072. {
  2073. PDNSSRV_QUERY_STATS pstat = ( PDNSSRV_QUERY_STATS ) pStat;
  2074. dwStat( L"Queries received", pstat->UdpQueries + pstat->TcpQueries );
  2075. dwStat( L"Responses sent", pstat->UdpResponses + pstat->TcpResponses );
  2076. dwStat( L"UDP queries received", pstat->UdpQueries );
  2077. dwStat( L"UDP responses sent", pstat->UdpResponses );
  2078. dwStat( L"UDP queries sent", pstat->UdpQueriesSent );
  2079. dwStat( L"UDP responses received", pstat->UdpResponsesReceived );
  2080. dwStat( L"TCP client connections", pstat->TcpClientConnections );
  2081. dwStat( L"TCP queries received", pstat->TcpQueries );
  2082. dwStat( L"TCP responses sent", pstat->TcpResponses );
  2083. dwStat( L"TCP queries sent", pstat->TcpQueriesSent );
  2084. dwStat( L"TCP responses received", pstat->TcpResponsesReceived );
  2085. break;
  2086. }
  2087. case DNSSRV_STATID_QUERY2:
  2088. {
  2089. PDNSSRV_QUERY2_STATS pstat = ( PDNSSRV_QUERY2_STATS ) pStat;
  2090. dwStat( L"Total queries", pstat->TotalQueries );
  2091. dwStat( L"Notify queries", pstat->Notify );
  2092. dwStat( L"Update queries", pstat->Update );
  2093. dwStat( L"TKeyNego queries", pstat->TKeyNego );
  2094. dwStat( L"Standard queries", pstat->Standard );
  2095. dwStat( L"A queries", pstat->TypeA );
  2096. dwStat( L"NS queries", pstat->TypeNs );
  2097. dwStat( L"SOA queries", pstat->TypeSoa );
  2098. dwStat( L"MX queries", pstat->TypeMx );
  2099. dwStat( L"PTR queries", pstat->TypePtr );
  2100. dwStat( L"SRV queries", pstat->TypeSrv );
  2101. dwStat( L"ALL queries", pstat->TypeAll );
  2102. dwStat( L"IXFR queries", pstat->TypeIxfr );
  2103. dwStat( L"AXFR queries", pstat->TypeAxfr );
  2104. dwStat( L"Other queries", pstat->TypeOther );
  2105. break;
  2106. }
  2107. case DNSSRV_STATID_RECURSE:
  2108. {
  2109. PDNSSRV_RECURSE_STATS pstat = ( PDNSSRV_RECURSE_STATS ) pStat;
  2110. dwStat( L"Queries recursed", pstat->QueriesRecursed );
  2111. dwStat( L"Original questions recursed", pstat->OriginalQuestionRecursed );
  2112. dwStat( L"Additional questions recursed", pstat->AdditionalRecursed );
  2113. dwStat( L"Total questions recursed", pstat->TotalQuestionsRecursed );
  2114. dwStat( L"Original questions recursed", pstat->OriginalQuestionRecursed );
  2115. dwStat( L"Retries", pstat->Retries );
  2116. dwStat( L"Total passes", pstat->LookupPasses );
  2117. dwStat( L"To forwarders", pstat->Forwards );
  2118. dwStat( L"Sends", pstat->Sends );
  2119. dwStat( L"Total responses", pstat->Responses );
  2120. dwStat( L"Responses unmatched", pstat->ResponseUnmatched );
  2121. dwStat( L"Responses mismatched", pstat->ResponseMismatched );
  2122. dwStat( L"Responses from forwarders", pstat->ResponseFromForwarder );
  2123. dwStat( L"Authoritative responses", pstat->ResponseAuthoritative );
  2124. dwStat( L"NotAuthoritative responses", pstat->ResponseNotAuth );
  2125. dwStat( L"Answer responses", pstat->ResponseAnswer );
  2126. dwStat( L"Empty responses", pstat->ResponseEmpty );
  2127. dwStat( L"Name error responses", pstat->ResponseAnswer );
  2128. dwStat( L"Rcode responses", pstat->ResponseRcode );
  2129. dwStat( L"Delegation responses", pstat->ResponseDelegation );
  2130. dwStat( L"Non-zone data responses", pstat->ResponseNonZoneData );
  2131. dwStat( L"Unsecure responses", pstat->ResponseUnsecure );
  2132. dwStat( L"Bad packet responses", pstat->ResponseBadPacket );
  2133. dwStat( L"Forwarded responses", pstat->SendResponseDirect );
  2134. dwStat( L"Continue current recursion responses", pstat->ContinueCurrentRecursion );
  2135. dwStat( L"Continue current lookup responses", pstat->ContinueCurrentLookup );
  2136. dwStat( L"Continue next lookup responses", pstat->ContinueNextLookup );
  2137. dwStat( L"Send timeouts", pstat->PacketTimeout );
  2138. dwStat( L"Final queued timeouts", pstat->FinalTimeoutQueued );
  2139. dwStat( L"Final timeouts expired", pstat->FinalTimeoutExpired );
  2140. dwStat( L"Recurse failures", pstat->RecursePassFailure );
  2141. dwStat( L"Into authority failures", pstat->FailureReachAuthority );
  2142. dwStat( L"Previous zone failures", pstat->FailureReachPreviousResponse );
  2143. dwStat( L"Retry count failures", pstat->FailureRetryCount );
  2144. dwStat( L"Cache update failures", pstat->CacheUpdateFailure );
  2145. dwStat( L"Server failure responses", pstat->ServerFailure );
  2146. dwStat( L"Total failures", pstat->Failures );
  2147. dwStat( L"TCP recursions tried", pstat->TcpTry );
  2148. dwStat( L"TCP recursion queries", pstat->TcpQuery );
  2149. dwStat( L"TCP recursion responses", pstat->TcpResponse );
  2150. dwStat( L"TCP recursion disconnects", pstat->TcpDisconnect );
  2151. dwStat( L"Cache update queries allocated", pstat->CacheUpdateAlloc );
  2152. dwStat( L"Cache update query responses", pstat->CacheUpdateResponse );
  2153. dwStat( L"Cache update query retries", pstat->CacheUpdateRetry );
  2154. dwStat( L"Cache update queries freed", pstat->CacheUpdateFree );
  2155. dwStat( L"Cache update queries for root NS", pstat->RootNsQuery );
  2156. dwStat( L"Cache update responses for root NS", pstat->RootNsResponse );
  2157. dwStat( L"Cache update queries suspended", pstat->SuspendedQuery );
  2158. dwStat( L"Cache update queries resumed", pstat->ResumeSuspendedQuery );
  2159. break;
  2160. }
  2161. case DNSSRV_STATID_MASTER:
  2162. {
  2163. PDNSSRV_MASTER_STATS pstat = ( PDNSSRV_MASTER_STATS ) pStat;
  2164. dwStat( L"Notifies sent", pstat->NotifySent );
  2165. dwStat( L"Requests", pstat->Request );
  2166. dwStat( L"NameErrors", pstat->NameError );
  2167. dwStat( L"FormErrors", pstat->FormError );
  2168. dwStat( L"Refused", pstat->Refused );
  2169. dwStat( L"AxfrLimit refused", pstat->AxfrLimit );
  2170. dwStat( L"Security refused", pstat->RefuseSecurity );
  2171. dwStat( L"Shutdown refused", pstat->RefuseShutdown );
  2172. dwStat( L"ServFail refused", pstat->RefuseServerFailure );
  2173. dwStat( L"Transfer failures", pstat->Failure );
  2174. dwStat( L"Transfer successes", pstat->AxfrSuccess + pstat->IxfrUpdateSuccess );
  2175. dwStat( L"AXFR requests", pstat->AxfrRequest );
  2176. dwStat( L"AXFR successes", pstat->AxfrSuccess );
  2177. dwStat( L"AXFR in IXFR", pstat->IxfrAxfr );
  2178. dwStat( L"IXFR requests", pstat->IxfrRequest );
  2179. dwStat( L"IXFR successes", pstat->IxfrUpdateSuccess );
  2180. dwStat( L"IXFR UDP requests", pstat->IxfrUdpRequest );
  2181. dwStat( L"IXFR UDP successes", pstat->IxfrUdpSuccess );
  2182. dwStat( L"IXFR UDP force TCP", pstat->IxfrUdpForceTcp );
  2183. dwStat( L"IXFR UDP force AXFR", pstat->IxfrUdpForceAxfr );
  2184. dwStat( L"IXFR TCP requests", pstat->IxfrTcpRequest );
  2185. dwStat( L"IXFR TCP successes", pstat->IxfrTcpSuccess );
  2186. dwStat( L"IXFR TCP force AXFR", pstat->IxfrAxfr );
  2187. break;
  2188. }
  2189. case DNSSRV_STATID_SECONDARY:
  2190. {
  2191. PDNSSRV_SECONDARY_STATS pstat = (PDNSSRV_SECONDARY_STATS)pStat;
  2192. dwStat( L"Notifies received", pstat->NotifyReceived );
  2193. dwStat( L"Notifies invalid", pstat->NotifyInvalid );
  2194. dwStat( L"Notifies primary", pstat->NotifyPrimary );
  2195. dwStat( L"Notifies no version", pstat->NotifyNoVersion );
  2196. dwStat( L"Notifies new version", pstat->NotifyNewVersion );
  2197. dwStat( L"Notifies current version", pstat->NotifyCurrentVersion );
  2198. dwStat( L"Notifies old version", pstat->NotifyOldVersion );
  2199. dwStat( L"Notifies master unknown", pstat->NotifyMasterUnknown );
  2200. dwStat( L"SOA requests", pstat->SoaRequest );
  2201. dwStat( L"SOA responses", pstat->SoaResponse );
  2202. dwStat( L"SOA invalid responses", pstat->SoaResponseInvalid );
  2203. dwStat( L"SOA NameError responses", pstat->SoaResponseNameError );
  2204. dwStat( L"AXFR requests", pstat->AxfrRequest );
  2205. dwStat( L"AXFR in IXFR requests", pstat->IxfrTcpAxfr );
  2206. dwStat( L"AXFR responses", pstat->AxfrResponse );
  2207. dwStat( L"AXFR success responses", pstat->AxfrSuccess );
  2208. dwStat( L"AXFR refused responses", pstat->AxfrRefused );
  2209. dwStat( L"AXFR invalid responses", pstat->AxfrInvalid );
  2210. dwStat( L"Stub zone AXFR requests", pstat->StubAxfrRequest );
  2211. dwStat( L"Stub zone AXFR responses", pstat->StubAxfrResponse );
  2212. dwStat( L"Stub zone AXFR success responses", pstat->StubAxfrSuccess );
  2213. dwStat( L"Stub zone AXFR refused responses", pstat->StubAxfrRefused );
  2214. dwStat( L"Stub zone AXFR invalid responses", pstat->StubAxfrInvalid );
  2215. dwStat( L"IXFR UDP requests", pstat->IxfrUdpRequest );
  2216. dwStat( L"IXFR UDP responses", pstat->IxfrUdpResponse );
  2217. dwStat( L"IXFR UDP success responses", pstat->IxfrUdpSuccess );
  2218. dwStat( L"IXFR UDP UseTcp responses", pstat->IxfrUdpUseTcp );
  2219. dwStat( L"IXFR UDP UseAxfr responses", pstat->IxfrUdpUseAxfr );
  2220. dwStat( L"IXFR UDP new primary responses", pstat->IxfrUdpNewPrimary );
  2221. dwStat( L"IXFR UDP refused responses", pstat->IxfrUdpRefused );
  2222. dwStat( L"IXFR UDP wrong server responses", pstat->IxfrUdpWrongServer );
  2223. dwStat( L"IXFR UDP FormError responses", pstat->IxfrUdpFormerr );
  2224. dwStat( L"IXFR UDP invalid responses", pstat->IxfrUdpInvalid );
  2225. dwStat( L"IXFR TCP requests", pstat->IxfrTcpRequest );
  2226. dwStat( L"IXFR TCP responses", pstat->IxfrTcpResponse );
  2227. dwStat( L"IXFR TCP success responses", pstat->IxfrTcpSuccess );
  2228. dwStat( L"IXFR TCP AXFR responses", pstat->IxfrTcpAxfr );
  2229. dwStat( L"IXFR TCP FormError responses", pstat->IxfrTcpFormerr );
  2230. dwStat( L"IXFR TCP refused responses", pstat->IxfrTcpRefused );
  2231. dwStat( L"IXFR TCP invalid responses", pstat->IxfrTcpInvalid );
  2232. break;
  2233. }
  2234. case DNSSRV_STATID_WINS:
  2235. {
  2236. PDNSSRV_WINS_STATS pstat = ( PDNSSRV_WINS_STATS ) pStat;
  2237. dwStat( L"WINS forward lookups", pstat->WinsLookups );
  2238. dwStat( L"WINS forward lookup responses", pstat->WinsResponses );
  2239. dwStat( L"WINS reverse lookups", pstat->WinsReverseLookups );
  2240. dwStat( L"WINS reverse lookup responses", pstat->WinsReverseResponses );
  2241. break;
  2242. }
  2243. case DNSSRV_STATID_NBSTAT:
  2244. {
  2245. PDNSSRV_NBSTAT_STATS pstat = (PDNSSRV_NBSTAT_STATS)pStat;
  2246. dwStat( L"Nbstat total buffers allocated", pstat->NbstatAlloc );
  2247. dwStat( L"Nbstat total buffers freed", pstat->NbstatFree );
  2248. dwStat( L"Nbstat net buffers allocated", pstat->NbstatNetAllocs );
  2249. dwStat( L"Nbstat net bytes allocated", pstat->NbstatMemory );
  2250. dwStat( L"Nbstat memory highwater mark", pstat->NbstatUsed );
  2251. dwStat( L"Nbstat buffers returned", pstat->NbstatReturn );
  2252. dwStat( L"Nbstat buffers in use", pstat->NbstatInUse );
  2253. dwStat( L"Nbstat buffers on free list", pstat->NbstatInFreeList );
  2254. break;
  2255. }
  2256. case DNSSRV_STATID_WIRE_UPDATE:
  2257. case DNSSRV_STATID_NONWIRE_UPDATE:
  2258. {
  2259. PDNSSRV_UPDATE_STATS pstat = ( PDNSSRV_UPDATE_STATS ) pStat;
  2260. dwStat( L"Updates received", pstat->Received );
  2261. dwStat( L"Updates forwarded", pstat->Forwards );
  2262. dwStat( L"Updates retried", pstat->Retry );
  2263. dwStat( L"Updates empty (precon only)", pstat->Empty );
  2264. dwStat( L"Updates NoOps (duplicates)", pstat->NoOps );
  2265. dwStat( L"Updates rejected", pstat->Rejected );
  2266. dwStat( L"Updates completed", pstat->Completed );
  2267. dwStat( L"Updates timed out", pstat->Timeout );
  2268. dwStat( L"Updates in queue", pstat->InQueue );
  2269. dwStat( L"Updates rejected", pstat->Rejected );
  2270. dwStat( L"Updates rejected with FormError", pstat->FormErr );
  2271. dwStat( L"Updates rejected with NameError", pstat->NxDomain );
  2272. dwStat( L"Updates rejected with NotImpl", pstat->NotImpl );
  2273. dwStat( L"Updates rejected with Refused", pstat->Refused );
  2274. dwStat( L"Updates rejected with Refused (nonsecure)", pstat->RefusedNonSecure );
  2275. dwStat( L"Updates rejected with Refused (access denied)", pstat->RefusedAccessDenied );
  2276. dwStat( L"Updates rejected with YxDomain", pstat->YxDomain );
  2277. dwStat( L"Updates rejected with YxRRSet", pstat->YxRrset );
  2278. dwStat( L"Updates rejected with NxRRSet", pstat->NxRrset );
  2279. dwStat( L"Updates rejected with NotAuth", pstat->NotAuth );
  2280. dwStat( L"Updates rejected with NotZone", pstat->NotZone );
  2281. dwStat( L"Secure update successes", pstat->SecureSuccess );
  2282. dwStat( L"Secure update continues", pstat->SecureContinue );
  2283. dwStat( L"Secure update failures", pstat->SecureFailure );
  2284. dwStat( L"Secure update DS write failures", pstat->SecureDsWriteFailure );
  2285. dwStat( L"Updates forwarded via TCP", pstat->TcpForwards );
  2286. dwStat( L"Responses for forwarded updates", pstat->ForwardResponses );
  2287. dwStat( L"Timeouts for forwarded updates", pstat->ForwardTimeouts );
  2288. dwStat( L"Forwarded updates in queue", pstat->ForwardInQueue );
  2289. dnsWrapAddStatisticsForTypeArray(
  2290. pClass,
  2291. pHandler,
  2292. statCollIdx,
  2293. L"Updates",
  2294. pstat->UpdateType );
  2295. break;
  2296. }
  2297. case DNSSRV_STATID_DS:
  2298. {
  2299. PDNSSRV_DS_STATS pstat = ( PDNSSRV_DS_STATS ) pStat;
  2300. dwStat( L"Nodes read", pstat->DsTotalNodesRead );
  2301. dwStat( L"Records read", pstat->DsTotalRecordsRead );
  2302. dwStat( L"Nodes loaded", pstat->DsNodesLoaded );
  2303. dwStat( L"Records loaded", pstat->DsRecordsLoaded );
  2304. dwStat( L"Update searches", pstat->DsUpdateSearches );
  2305. dwStat( L"Update nodes read", pstat->DsUpdateNodesRead );
  2306. dwStat( L"Update records read", pstat->DsUpdateRecordsRead );
  2307. dwStat( L"Nodes added", pstat->DsNodesAdded );
  2308. dwStat( L"Nodes modified", pstat->DsNodesModified );
  2309. dwStat( L"Nodes tombstoned", pstat->DsNodesTombstoned );
  2310. dwStat( L"Tombstones read", pstat->DsTombstonesRead );
  2311. dwStat( L"Nodes deleted", pstat->DsNodesDeleted );
  2312. dwStat( L"Nodes write suppressed", pstat->DsWriteSuppressed );
  2313. dwStat( L"RR sets added", pstat->DsRecordsAdded );
  2314. dwStat( L"RR sets replaced", pstat->DsRecordsReplaced );
  2315. dwStat( L"Serial number writes", pstat->DsSerialWrites );
  2316. dwStat( L"Update lists", pstat->UpdateLists );
  2317. dwStat( L"Update nodes", pstat->UpdateNodes );
  2318. dwStat( L"Updates suppressed ", pstat->UpdateSuppressed );
  2319. dwStat( L"Update writes", pstat->UpdateWrites );
  2320. dwStat( L"Update tombstones", pstat->UpdateTombstones );
  2321. dwStat( L"Update record changes", pstat->UpdateRecordChange );
  2322. dwStat( L"Update aging refresh", pstat->UpdateAgingRefresh );
  2323. dwStat( L"Update aging on", pstat->UpdateAgingOn );
  2324. dwStat( L"Update aging off", pstat->UpdateAgingOff );
  2325. dwStat( L"Update from packet", pstat->UpdatePacket );
  2326. dwStat( L"Update from packet (precon)", pstat->UpdatePacketPrecon );
  2327. dwStat( L"Update from admin", pstat->UpdateAdmin );
  2328. dwStat( L"Update from auto config", pstat->UpdateAutoConfig );
  2329. dwStat( L"Update from scavenge", pstat->UpdateScavenge );
  2330. dwStat( L"LDAP timed writes", pstat->LdapTimedWrites );
  2331. dwStat( L"LDAP total write time", pstat->LdapWriteTimeTotal );
  2332. dwStat( L"LDAP average write time", pstat->LdapWriteAverage );
  2333. dwStat( L"LDAP writes < 10 ms", pstat->LdapWriteBucket0 );
  2334. dwStat( L"LDAP writes < 100 ms", pstat->LdapWriteBucket1 );
  2335. dwStat( L"LDAP writes < 1 s", pstat->LdapWriteBucket2 );
  2336. dwStat( L"LDAP writes < 10 s", pstat->LdapWriteBucket3 );
  2337. dwStat( L"LDAP writes < 100 s", pstat->LdapWriteBucket4 );
  2338. dwStat( L"LDAP writes > 100 s", pstat->LdapWriteBucket5 );
  2339. dwStat( L"LDAP writes max timeout", pstat->LdapWriteMax );
  2340. dwStat( L"Total LDAP search time", pstat->LdapSearchTime );
  2341. dwStat( L"Failed deletions", pstat->FailedDeleteDsEntries );
  2342. dwStat( L"Failed reads", pstat->FailedReadRecords );
  2343. dwStat( L"Failed modifies", pstat->FailedLdapModify );
  2344. dwStat( L"Failed adds", pstat->FailedLdapAdd );
  2345. dwStat( L"Polling passes with DS errors", pstat->PollingPassesWithDsErrors );
  2346. dwStat( L"LDAP reconnects", pstat->LdapReconnects );
  2347. dnsWrapAddStatisticsForTypeArray(
  2348. pClass,
  2349. pHandler,
  2350. statCollIdx,
  2351. L"LDAP writes",
  2352. pstat->DsWriteType );
  2353. break;
  2354. }
  2355. case DNSSRV_STATID_SKWANSEC:
  2356. {
  2357. PDNSSRV_SKWANSEC_STATS pstat = ( PDNSSRV_SKWANSEC_STATS ) pStat;
  2358. dwStat( L"Security contexts created", pstat->SecContextCreate );
  2359. dwStat( L"Security contexts freed", pstat->SecContextFree );
  2360. dwStat( L"Security contexts timed out", pstat->SecContextTimeout );
  2361. dwStat( L"Security contexts queue length", pstat->SecContextQueueLength );
  2362. dwStat( L"Security contexts queued", pstat->SecContextQueue );
  2363. dwStat( L"Security contexts queued in negotiation", pstat->SecContextQueueInNego );
  2364. dwStat( L"Security contexts queued negotiation complete", pstat->SecContextQueueNegoComplete );
  2365. dwStat( L"Security contexts dequeued", pstat->SecContextDequeue );
  2366. dwStat( L"Security packet contexts allocated", pstat->SecPackAlloc );
  2367. dwStat( L"Security packet contexts freed", pstat->SecPackFree );
  2368. dwStat( L"Invalid TKEYs", pstat->SecTkeyInvalid );
  2369. dwStat( L"Bad time TKEYs", pstat->SecTkeyBadTime );
  2370. dwStat( L"FormErr TSIGs", pstat->SecTsigFormerr );
  2371. dwStat( L"Echo TSIGs", pstat->SecTsigEcho );
  2372. dwStat( L"BadKey TSIGs", pstat->SecTsigBadKey );
  2373. dwStat( L"Verify success TSIGs", pstat->SecTsigVerifySuccess );
  2374. dwStat( L"Verify failed TSIGs", pstat->SecTsigVerifyFailed );
  2375. break;
  2376. }
  2377. case DNSSRV_STATID_MEMORY:
  2378. {
  2379. PDNSSRV_MEMORY_STATS pstat = ( PDNSSRV_MEMORY_STATS ) pStat;
  2380. LPSTR * pnameArray = MemTagStrings;
  2381. DWORD count = MEMTAG_COUNT;
  2382. dwStat( L"Total memory", pstat->StdUsed );
  2383. dwStat( L"Allocation count", pstat->Alloc );
  2384. dwStat( L"Free count", pstat->Free );
  2385. dwStat( L"Standard allocs used", pstat->StdUsed );
  2386. dwStat( L"Standard allocs returned", pstat->StdReturn );
  2387. dwStat( L"Standard allocs in use", pstat->StdInUse );
  2388. dwStat( L"Standard allocs memory", pstat->StdMemory );
  2389. dwStat( L"Standard to heap allocs used", pstat->StdToHeapAlloc );
  2390. dwStat( L"Standard to heap allocs returned", pstat->StdToHeapFree );
  2391. dwStat( L"Standard to heap allocs in use", pstat->StdToHeapInUse );
  2392. dwStat( L"Standard to heap allocs memory", pstat->StdToHeapMemory );
  2393. dwStat( L"Standard blocks allocated", pstat->StdBlockAlloc );
  2394. dwStat( L"Standard blocks used", pstat->StdBlockUsed );
  2395. dwStat( L"Standard blocks returned", pstat->StdBlockReturn );
  2396. dwStat( L"Standard blocks in use", pstat->StdBlockInUse );
  2397. dwStat( L"Standard blocks in free list", pstat->StdBlockFreeList );
  2398. dwStat( L"Standard block memory in free list", pstat->StdBlockFreeListMemory );
  2399. dwStat( L"Standard block total memory", pstat->StdBlockMemory );
  2400. for ( DWORD i = 0; i < count; ++i )
  2401. {
  2402. WCHAR sz[ 80 ];
  2403. wsprintfW( sz, L"%S blocks allocated", pnameArray[ i ] );
  2404. dwStat( sz, pstat->MemTags[ i ].Alloc );
  2405. wsprintfW( sz, L"%S blocks freed", pnameArray[ i ] );
  2406. dwStat( sz, pstat->MemTags[ i ].Free );
  2407. wsprintfW( sz, L"%S blocks in use", pnameArray[ i ] );
  2408. dwStat( sz, pstat->MemTags[ i ].Alloc - pstat->MemTags[ i ].Free );
  2409. wsprintfW( sz, L"%S memory", pnameArray[ i ] );
  2410. dwStat( sz, pstat->MemTags[ i ].Memory );
  2411. }
  2412. break;
  2413. }
  2414. case DNSSRV_STATID_DBASE:
  2415. {
  2416. PDNSSRV_DBASE_STATS pstat = ( PDNSSRV_DBASE_STATS ) pStat;
  2417. dwStat( L"Database nodes used", pstat->NodeUsed );
  2418. dwStat( L"Database nodes returned", pstat->NodeReturn );
  2419. dwStat( L"Database nodes in use", pstat->NodeInUse );
  2420. dwStat( L"Database nodes memory", pstat->NodeMemory );
  2421. break;
  2422. }
  2423. case DNSSRV_STATID_RECORD:
  2424. {
  2425. PDNSSRV_RECORD_STATS pstat = ( PDNSSRV_RECORD_STATS ) pStat;
  2426. dwStat( L"Records used", pstat->Used );
  2427. dwStat( L"Records returned", pstat->Return );
  2428. dwStat( L"Records in use", pstat->InUse );
  2429. dwStat( L"Records memory", pstat->Memory );
  2430. dwStat( L"Records queued for slow free", pstat->SlowFreeQueued );
  2431. dwStat( L"Records slow freed", pstat->SlowFreeFinished );
  2432. dwStat( L"Total records cached", pstat->CacheTotal );
  2433. dwStat( L"Records currently cached", pstat->CacheCurrent );
  2434. dwStat( L"Cached records timed out", pstat->CacheTimeouts );
  2435. break;
  2436. }
  2437. case DNSSRV_STATID_PACKET:
  2438. {
  2439. PDNSSRV_PACKET_STATS pstat = ( PDNSSRV_PACKET_STATS ) pStat;
  2440. dwStat( L"UDP messages allocated", pstat->UdpAlloc );
  2441. dwStat( L"UDP messages freed", pstat->UdpFree );
  2442. dwStat( L"UDP messages net allocations", pstat->UdpNetAllocs );
  2443. dwStat( L"UDP messages memory", pstat->UdpMemory );
  2444. dwStat( L"UDP messages used", pstat->UdpUsed );
  2445. dwStat( L"UDP messages returned", pstat->UdpReturn );
  2446. dwStat( L"UDP messages in use", pstat->UdpInUse );
  2447. dwStat( L"UDP messages in free list", pstat->UdpInFreeList );
  2448. dwStat( L"UDP messages allocated", pstat->TcpAlloc );
  2449. dwStat( L"UDP messages reallocated", pstat->TcpRealloc );
  2450. dwStat( L"UDP messages freed", pstat->TcpFree );
  2451. dwStat( L"UDP messages net allocations", pstat->TcpNetAllocs );
  2452. dwStat( L"UDP messages memory", pstat->TcpMemory );
  2453. dwStat( L"Recursion messages used", pstat->RecursePacketUsed );
  2454. dwStat( L"Recursion messages returned", pstat->RecursePacketReturn );
  2455. break;
  2456. }
  2457. case DNSSRV_STATID_TIMEOUT:
  2458. {
  2459. PDNSSRV_TIMEOUT_STATS pstat = ( PDNSSRV_TIMEOUT_STATS ) pStat;
  2460. dwStat( L"Nodes queued", pstat->SetTotal );
  2461. dwStat( L"Nodes directed queued", pstat->SetDirect );
  2462. dwStat( L"Nodes queued from reference", pstat->SetFromDereference );
  2463. dwStat( L"Nodes queued from child delete", pstat->SetFromChildDelete );
  2464. dwStat( L"Nodes duplicate (already queued)", pstat->AlreadyInSystem );
  2465. dwStat( L"Nodes checked", pstat->Checks );
  2466. dwStat( L"Recent access nodes checked", pstat->RecentAccess );
  2467. dwStat( L"Active record nodes checked", pstat->ActiveRecord );
  2468. dwStat( L"Can not delete nodes checked", pstat->CanNotDelete );
  2469. dwStat( L"Deleted nodes checked", pstat->Deleted );
  2470. dwStat( L"Timeout blocks created", pstat->ArrayBlocksCreated );
  2471. dwStat( L"Timeout blocks deleted", pstat->ArrayBlocksDeleted );
  2472. dwStat( L"Delayed frees queued", pstat->DelayedFreesQueued );
  2473. dwStat( L"Delayed frees queued with function", pstat->DelayedFreesQueuedWithFunction );
  2474. dwStat( L"Delayed frees executed", pstat->DelayedFreesExecuted );
  2475. dwStat( L"Delayed frees executed with function", pstat->DelayedFreesExecutedWithFunction );
  2476. break;
  2477. }
  2478. case DNSSRV_STATID_ERRORS:
  2479. {
  2480. PDNSSRV_ERROR_STATS pstat = ( PDNSSRV_ERROR_STATS ) pStat;
  2481. dwStat( L"NoError", pstat->NoError );
  2482. dwStat( L"FormError", pstat->FormError );
  2483. dwStat( L"ServFail", pstat->ServFail );
  2484. dwStat( L"NxDomain", pstat->NxDomain );
  2485. dwStat( L"NotImpl", pstat->NotImpl );
  2486. dwStat( L"Refused", pstat->Refused );
  2487. dwStat( L"YxDomain", pstat->YxDomain );
  2488. dwStat( L"YxRRSet", pstat->YxRRSet );
  2489. dwStat( L"NxRRSet", pstat->NxRRSet );
  2490. dwStat( L"NotAuth", pstat->NotAuth );
  2491. dwStat( L"NotZone", pstat->NotZone );
  2492. dwStat( L"Max", pstat->Max );
  2493. dwStat( L"BadSig", pstat->BadSig );
  2494. dwStat( L"BadKey", pstat->BadKey );
  2495. dwStat( L"BadTime", pstat->BadTime );
  2496. dwStat( L"UnknownError", pstat->UnknownError );
  2497. break;
  2498. }
  2499. case DNSSRV_STATID_CACHE:
  2500. {
  2501. PDNSSRV_CACHE_STATS pstat = ( PDNSSRV_CACHE_STATS ) pStat;
  2502. dwStat( L"Checks where cache exceeded limit", pstat->CacheExceededLimitChecks );
  2503. dwStat( L"Successful cache enforcement passes", pstat->SuccessfulFreePasses );
  2504. dwStat( L"Failed cache enforcement passes", pstat->FailedFreePasses );
  2505. dwStat( L"Passes requiring aggressive free", pstat->PassesRequiringAggressiveFree );
  2506. dwStat( L"Passes where nothing was freed", pstat->PassesWithNoFrees );
  2507. break;
  2508. }
  2509. default:
  2510. break;
  2511. }
  2512. //
  2513. // Cleanup and return.
  2514. //
  2515. return sc;
  2516. }
  2517. SCODE
  2518. CDnsWrap::dnsGetStatistics(
  2519. IWbemClassObject * pClass,
  2520. IWbemObjectSink * pHandler,
  2521. DWORD dwStatId
  2522. )
  2523. /*++
  2524. Routine Description:
  2525. Retrieve DNS statistics.
  2526. Arguments:
  2527. dwStatId -- statistic ID or zero for all
  2528. pClass -- ptr to StatisticsCollection class object
  2529. Return Value:
  2530. None
  2531. --*/
  2532. {
  2533. SCODE sc = S_OK;
  2534. DNS_STATUS status = ERROR_SUCCESS;
  2535. PDNS_RPC_BUFFER pstatbuff = NULL;
  2536. BSTR bstrStatClass = NULL;
  2537. IWbemClassObject * pStatClass = NULL;
  2538. //
  2539. // Retrieve RPC stat buffer from server.
  2540. //
  2541. if ( dwStatId == 0 )
  2542. {
  2543. dwStatId = DNSSRV_STATID_ALL;
  2544. }
  2545. status = DnssrvGetStatistics(
  2546. PVD_DNS_LOCAL_SERVER,
  2547. dwStatId,
  2548. &pstatbuff );
  2549. if ( status != ERROR_SUCCESS )
  2550. {
  2551. ThrowException( status );
  2552. }
  2553. if ( !pstatbuff )
  2554. {
  2555. ThrowException( ERROR_NO_DATA );
  2556. }
  2557. //
  2558. // Iterate stats in buffer. Add each "single stat" in the buffer
  2559. // to the WMI instance as a StatisticCollection. Add each individual
  2560. // statistics in each "single stat" buffer as a value to that
  2561. // statistic collection.
  2562. //
  2563. PDNSSRV_STAT pstat;
  2564. PBYTE pch = pstatbuff ? &pstatbuff->Buffer[ 0 ] : NULL;
  2565. PBYTE pchstop = pstatbuff ? pch + pstatbuff->dwLength : NULL;
  2566. while ( sc == S_OK && pch < pchstop )
  2567. {
  2568. pstat = ( PDNSSRV_STAT ) pch;
  2569. pch = ( PBYTE ) GET_NEXT_STAT_IN_BUFFER( pstat );
  2570. sc = dnsWrapHandleSingleStat( pClass, pHandler, pstat );
  2571. if ( sc != S_OK )
  2572. {
  2573. break;
  2574. }
  2575. }
  2576. //
  2577. // Cleanup and return.
  2578. //
  2579. SysFreeString( bstrStatClass );
  2580. if ( pstatbuff )
  2581. {
  2582. MIDL_user_free( pstatbuff );
  2583. }
  2584. if ( pStatClass )
  2585. {
  2586. pStatClass->Release();
  2587. }
  2588. return sc;
  2589. } // CDnsWrap::dnsGetStatistics