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.

1338 lines
37 KiB

  1. /////////////////////////////////////////////////////////////////////
  2. //
  3. // CopyRight ( c ) 1999 Microsoft Corporation
  4. //
  5. // Module Name: Dnsresourcerecord.cpp
  6. //
  7. // Description:
  8. // Implementation of CDnsResourceRecord class
  9. //
  10. // Author:
  11. // Henry Wang ( henrywa ) March 8, 2000
  12. //
  13. //
  14. //////////////////////////////////////////////////////////////////////
  15. #include "DnsWmi.h"
  16. //////////////////////////////////////////////////////////////////////
  17. // Construction/Destruction
  18. //////////////////////////////////////////////////////////////////////
  19. CDnsResourceRecord::CDnsResourceRecord()
  20. {
  21. }
  22. /////////////////////////////////////////////////////////////////////////////
  23. //++
  24. //
  25. // Description:
  26. // create an instance of CDnsResourceRecord
  27. //
  28. // Arguments:
  29. // wszName [IN] class name
  30. // pNamespace [IN] wmi namespace
  31. // szType [IN] child class name of resource record class
  32. //
  33. // Return Value:
  34. // WBEM_S_NO_ERROR
  35. //
  36. //--
  37. /////////////////////////////////////////////////////////////////////////////
  38. CDnsBase*
  39. CDnsResourceRecord::CreateThis(
  40. const WCHAR * wszName,
  41. CWbemServices * pNamespace,
  42. const char * szType
  43. )
  44. {
  45. return new CDnsResourceRecord(wszName, pNamespace, szType);
  46. }
  47. CDnsResourceRecord::CDnsResourceRecord(
  48. const WCHAR* wszName,
  49. CWbemServices *pNamespace,
  50. const char* szType)
  51. :CDnsBase(wszName, pNamespace)
  52. {
  53. m_wType = Dns_RecordTypeForName(
  54. (char*)szType,
  55. 0 // null terminated
  56. );
  57. if(m_wType == 0)
  58. m_wType = DNS_TYPE_ALL;
  59. m_wstrClassName = wszName;
  60. }
  61. CDnsResourceRecord::~CDnsResourceRecord()
  62. {
  63. }
  64. CDnsResourceRecord::CDnsResourceRecord(
  65. WCHAR* wsClass,
  66. char* szType)
  67. {
  68. m_wType = Dns_RecordTypeForName(
  69. szType,
  70. 0 // null terminated
  71. );
  72. if(m_wType == 0)
  73. m_wType = DNS_TYPE_ALL;
  74. m_wstrClassName = wsClass;
  75. }
  76. /////////////////////////////////////////////////////////////////////////////
  77. //++
  78. //
  79. // Description:
  80. // enum instances of dns record
  81. //
  82. // Arguments:
  83. // lFlags [IN] WMI flag
  84. // pCtx [IN] WMI context
  85. // pHandler [IN] WMI sink pointer
  86. //
  87. // Return Value:
  88. // WBEM_S_NO_ERROR
  89. //
  90. //--
  91. /////////////////////////////////////////////////////////////////////////////
  92. SCODE
  93. CDnsResourceRecord::EnumInstance(
  94. long lFlags,
  95. IWbemContext * pCtx,
  96. IWbemObjectSink * pHandler)
  97. {
  98. IWbemClassObject* pNewInst;
  99. list<CDomainNode> objList;
  100. CDnsWrap& dns = CDnsWrap::DnsObject();
  101. SCODE sc = dns.dnsEnumDomainForServer(&objList);
  102. list<CDomainNode>::iterator i;
  103. CWbemInstanceMgr InstanceMgr(
  104. pHandler);
  105. for(i=objList.begin(); i!=objList.end(); ++i)
  106. {
  107. sc = dns.dnsEnumRecordsForDomainEx(
  108. *i,
  109. NULL,
  110. &InstanceFilter,
  111. TRUE,
  112. m_wType,
  113. DNS_RPC_VIEW_ALL_DATA,
  114. m_pClass,
  115. InstanceMgr);
  116. }
  117. return sc;
  118. }
  119. /////////////////////////////////////////////////////////////////////////////
  120. //++
  121. //
  122. // Description:
  123. // retrieve record object pointed by the given object path
  124. //
  125. // Arguments:
  126. // ObjectPath [IN] object path to object
  127. // lFlags [IN] WMI flag
  128. // pCtx [IN] WMI context
  129. // pHandler [IN] WMI sink pointer
  130. //
  131. // Return Value:
  132. // WBEM_S_NO_ERROR
  133. //
  134. //--
  135. /////////////////////////////////////////////////////////////////////////////
  136. SCODE
  137. CDnsResourceRecord::GetObject(
  138. CObjPath & ObjectPath,
  139. long lFlags,
  140. IWbemContext * pCtx,
  141. IWbemObjectSink * pHandler)
  142. {
  143. CDomainNode objNode;
  144. objNode.wstrZoneName = ObjectPath.GetStringValueForProperty(
  145. PVD_REC_CONTAINER_NAME );
  146. wstring wstrNodeName = ObjectPath.GetStringValueForProperty(
  147. PVD_REC_DOMAIN_NAME );
  148. if(_wcsicmp(wstrNodeName.data(), PVD_DNS_CACHE) == 0 ||
  149. _wcsicmp(wstrNodeName.data(), PVD_DNS_ROOTHINTS) ==0)
  150. {
  151. wstrNodeName = L"";
  152. ObjectPath.SetProperty(PVD_REC_OWNER_NAME,L"");
  153. }
  154. objNode.wstrNodeName = wstrNodeName;
  155. CDnsWrap& dns = CDnsWrap::DnsObject();
  156. CWbemInstanceMgr InstMgr(
  157. pHandler);
  158. SCODE sc = dns.dnsEnumRecordsForDomainEx(
  159. objNode,
  160. &ObjectPath,
  161. &GetObjectFilter,
  162. FALSE,
  163. m_wType,
  164. DNS_RPC_VIEW_ALL_DATA,
  165. m_pClass,
  166. InstMgr);
  167. return sc;
  168. }
  169. /////////////////////////////////////////////////////////////////////////////
  170. //++
  171. //
  172. // Description:
  173. // execute methods defined for record class in the mof
  174. //
  175. // Arguments:
  176. // ObjPath [IN] pointing to the object that the
  177. // method should be performed on
  178. // wzMethodName [IN] name of the method to be invoked
  179. // lFlags [IN] WMI flag
  180. // pInParams [IN] Input parameters for the method
  181. // pHandler [IN] WMI sink pointer
  182. //
  183. // Return Value:
  184. // WBEM_S_NO_ERROR
  185. // WBEM_E_INVALID_PARAMETER
  186. //
  187. //--
  188. /////////////////////////////////////////////////////////////////////////////
  189. SCODE CDnsResourceRecord::ExecuteMethod(
  190. CObjPath & ObjPath,
  191. WCHAR * wzMethodName,
  192. long lFlag,
  193. IWbemClassObject * pInArgs,
  194. IWbemObjectSink * pHandler)
  195. {
  196. CDnsWrap& dns = CDnsWrap::DnsObject();
  197. SCODE sc;
  198. CComPtr<IWbemClassObject> pOutParams;
  199. CComPtr<IWbemClassObject> pOutClass;
  200. sc = m_pClass->GetMethod(wzMethodName, 0, NULL, &pOutClass);
  201. if(sc != S_OK)
  202. {
  203. return sc;
  204. }
  205. pOutClass->SpawnInstance(0, &pOutParams);
  206. if(_wcsicmp(
  207. wzMethodName,
  208. PVD_MTH_REC_GETOBJECTBYTEXT) == 0)
  209. {
  210. return GetObjectFromText(
  211. pInArgs,
  212. pOutParams,
  213. pHandler);
  214. }
  215. else if(_wcsicmp(
  216. wzMethodName,
  217. PVD_MTH_REC_CREATEINSTANCEFROMTEXTREPRESENTATION) == 0)
  218. {
  219. return CreateInstanceFromText(
  220. pInArgs,
  221. pOutParams,
  222. pHandler);
  223. }
  224. else if (_wcsicmp(
  225. wzMethodName,
  226. PVD_MTH_REC_CREATEINSTANCEFROMPROPERTYDATA) == 0)
  227. {
  228. return CreateInstanceFromProperty(
  229. pInArgs,
  230. pOutParams,
  231. pHandler);
  232. }
  233. else if (_wcsicmp(
  234. wzMethodName,
  235. PVD_MTH_REC_MODIFY) == 0)
  236. {
  237. return Modify(ObjPath,
  238. pInArgs,
  239. pOutParams,
  240. pHandler);
  241. }
  242. else
  243. {
  244. return WBEM_E_NOT_SUPPORTED;
  245. }
  246. }
  247. /////////////////////////////////////////////////////////////////////////////
  248. //++
  249. //
  250. // Description:
  251. // call back function to enum record instance.
  252. //
  253. // Arguments:
  254. // ParentDomain [IN] Parent domain
  255. // pFilter [IN] pointer to object that contains the criteria to filter
  256. // which instance should be send to wmi
  257. // not used here
  258. // pNode [IN] pointer to Dns Rpc Node object
  259. // pClass [IN] wmi class used to create instance
  260. // InstMgr [IN] a ref to Instance manager obj that is
  261. // responsible to send mutiple instance
  262. // back to wmi at once
  263. //
  264. // Return Value:
  265. // WBEM_S_NO_ERROR
  266. //
  267. //--
  268. /////////////////////////////////////////////////////////////////////////////
  269. SCODE
  270. CDnsResourceRecord::InstanceFilter(
  271. CDomainNode & ParentDomain,
  272. PVOID pFilter,
  273. CDnsRpcNode * pNode,
  274. IWbemClassObject * pClass,
  275. CWbemInstanceMgr & InstMgr )
  276. {
  277. if(!pNode || !pClass )
  278. return WBEM_E_FAILED;
  279. if (pNode->IsDomainNode())
  280. return 0;
  281. CDnsRpcRecord* pRec=NULL;
  282. CDnsWrap& dns = CDnsWrap::DnsObject();
  283. wstring wzContainer = ParentDomain.wstrZoneName;
  284. wstring wstrFQDN;
  285. if( ParentDomain.wstrNodeName.empty())
  286. {
  287. wstrFQDN = ParentDomain.wstrZoneName;
  288. }
  289. else
  290. {
  291. wstrFQDN = ParentDomain.wstrNodeName;
  292. }
  293. wstring wstrNodeName = pNode->GetNodeName();
  294. if (!wstrNodeName.empty())
  295. {
  296. wstrNodeName += PVD_DNS_LOCAL_SERVER + wstrFQDN;
  297. }
  298. else
  299. {
  300. wstrNodeName = wstrFQDN;
  301. }
  302. while( (pRec = pNode->GetNextRecord()) != NULL)
  303. {
  304. auto_ptr<CDnsRpcRecord> apRec(pRec);
  305. CWbemClassObject NewInst;
  306. pClass->SpawnInstance(0, &NewInst);
  307. NewInst.SetProperty(
  308. dns.GetServerName(),
  309. PVD_REC_SERVER_NAME);
  310. NewInst.SetProperty(
  311. wzContainer,
  312. PVD_REC_CONTAINER_NAME);
  313. NewInst.SetProperty(
  314. wstrFQDN,
  315. PVD_REC_DOMAIN_NAME);
  316. NewInst.SetProperty(
  317. wstrNodeName,
  318. PVD_REC_OWNER_NAME);
  319. NewInst.SetProperty(
  320. pRec->GetTextRepresentation(wstrNodeName),
  321. PVD_REC_TXT_REP);
  322. apRec->ConvertToWbemObject(NewInst);
  323. InstMgr.Indicate(NewInst.data());
  324. }
  325. return WBEM_S_NO_ERROR;
  326. }
  327. /////////////////////////////////////////////////////////////////////////////
  328. //++
  329. //
  330. // Description:
  331. // call back function in response to ExceQuery call. Return instances
  332. // that satisfy query language
  333. //
  334. // Arguments:
  335. // ParentDomain [IN] Parent domain
  336. // pFilter [IN] pointer to CSqlEval object that implements
  337. // logic based on sql language to filter
  338. // which instance should be send to wmi
  339. // not used here
  340. // pNode [IN] pointer to Dns Rpc Node object
  341. // pClass [IN] wmi class used to create instance
  342. // InstMgr [IN] a ref to Instance manager obj that is
  343. // responsible to send mutiple instance
  344. // back to wmi at once
  345. //
  346. // Return Value:
  347. // WBEM_S_NO_ERROR
  348. //
  349. //--
  350. /////////////////////////////////////////////////////////////////////////////
  351. SCODE CDnsResourceRecord::QueryFilter(
  352. CDomainNode & ParentDomain,
  353. PVOID pFilter,
  354. CDnsRpcNode * pNode,
  355. IWbemClassObject * pClass,
  356. CWbemInstanceMgr & InstMgr )
  357. {
  358. DBG_FN( "CDnsResourceRecord::QueryFilter" );
  359. if(!pNode || !pClass || !pFilter)
  360. {
  361. return WBEM_E_FAILED;
  362. }
  363. if (pNode->IsDomainNode())
  364. {
  365. return 0;
  366. }
  367. CSqlEval* pFilterObj = (CSqlEval*) pFilter;
  368. CDnsRpcRecord* pRec=NULL;
  369. CDnsWrap& dns = CDnsWrap::DnsObject();
  370. wstring wzContainer = ParentDomain.wstrZoneName;
  371. wstring wstrFQDN;
  372. if( ParentDomain.wstrNodeName.empty())
  373. {
  374. wstrFQDN = ParentDomain.wstrZoneName;
  375. }
  376. else
  377. {
  378. wstrFQDN = ParentDomain.wstrNodeName;
  379. }
  380. wstring wstrNodeName = pNode->GetNodeName();
  381. if (!wstrNodeName.empty())
  382. {
  383. wstrNodeName += PVD_DNS_LOCAL_SERVER + wstrFQDN;
  384. }
  385. else
  386. {
  387. wstrNodeName = wstrFQDN;
  388. }
  389. while( (pRec = pNode->GetNextRecord()) != NULL)
  390. {
  391. auto_ptr<CDnsRpcRecord> apRec(pRec);
  392. CWbemClassObject NewInst;
  393. pClass->SpawnInstance(0, &NewInst);
  394. NewInst.SetProperty(
  395. dns.GetServerName(),
  396. PVD_REC_SERVER_NAME);
  397. NewInst.SetProperty(
  398. wzContainer,
  399. PVD_REC_CONTAINER_NAME);
  400. NewInst.SetProperty(
  401. wstrFQDN,
  402. PVD_REC_DOMAIN_NAME);
  403. NewInst.SetProperty(
  404. wstrNodeName,
  405. PVD_REC_OWNER_NAME);
  406. NewInst.SetProperty(
  407. pRec->GetTextRepresentation(wstrNodeName),
  408. PVD_REC_TXT_REP);
  409. pRec->ConvertToWbemObject(NewInst);
  410. CSqlWmiEvalee sqlEvalee( NewInst.data() );
  411. if( pFilterObj->Evaluate( &sqlEvalee ) )
  412. {
  413. DNS_DEBUG( RPCRR, (
  414. "%s: indicating node %S %S\n", fn,
  415. wstrNodeName.c_str(),
  416. pRec->GetTextRepresentation(wstrNodeName).c_str() ));
  417. InstMgr.Indicate( NewInst.data() );
  418. }
  419. else
  420. {
  421. DNS_DEBUG( RPCRR, (
  422. "%s: not indicating node %S %S\n", fn,
  423. wstrNodeName.c_str(),
  424. pRec->GetTextRepresentation(wstrNodeName).c_str() ));
  425. }
  426. }
  427. return WBEM_S_NO_ERROR;
  428. }
  429. /////////////////////////////////////////////////////////////////////////////
  430. //++
  431. //
  432. // Description:
  433. // call back function to enum record instance.
  434. //
  435. // Arguments:
  436. // ParentDomain [IN] Parent domain
  437. // pFilter [IN] pointer to an CObjPath object that
  438. // contains the criteria to filter
  439. // which instance should be send to wmi
  440. // not used here
  441. // pNode [IN] pointer to Dns Rpc Node object
  442. // pClass [IN] wmi class used to create instance
  443. // InstMgr [IN] a ref to Instance manager obj that is
  444. // responsible to send mutiple instance
  445. // back to wmi at once
  446. //
  447. // Return Value:
  448. // WBEM_S_NO_ERROR
  449. //
  450. //--
  451. /////////////////////////////////////////////////////////////////////////////
  452. SCODE
  453. CDnsResourceRecord::GetObjectFilter(
  454. CDomainNode & ParentDomain,
  455. PVOID pFilter,
  456. CDnsRpcNode * pNode,
  457. IWbemClassObject * pClass,
  458. CWbemInstanceMgr & InstMgr )
  459. {
  460. if(!pNode || !pClass || !pFilter)
  461. return WBEM_E_FAILED;
  462. if (pNode->IsDomainNode())
  463. return 0;
  464. CObjPath* pFilterObj = (CObjPath*) pFilter;
  465. CDnsRpcRecord* pRec=NULL;
  466. wstring wstrResultOwner = pNode->GetNodeName();
  467. if(wstrResultOwner.empty())
  468. wstrResultOwner = ParentDomain.wstrNodeName;
  469. else
  470. wstrResultOwner += PVD_DNS_LOCAL_SERVER + ParentDomain.wstrNodeName;
  471. while( (pRec = pNode->GetNextRecord()) != NULL)
  472. {
  473. auto_ptr<CDnsRpcRecord> apRec(pRec);
  474. wstring wstrSourceOwner =
  475. pFilterObj->GetStringValueForProperty(
  476. PVD_REC_OWNER_NAME);
  477. if(_wcsicmp(wstrResultOwner.data(), wstrSourceOwner.data())==0)
  478. {
  479. wstring wstrData = pRec->GetData();
  480. if(_wcsicmp(wstrData.data(),
  481. pFilterObj->GetStringValueForProperty(
  482. PVD_REC_RDATA).data()) == 0)
  483. {
  484. // now find match
  485. CWbemClassObject NewInst;
  486. pClass->SpawnInstance(0, &NewInst);
  487. NewInst.SetProperty(
  488. CDnsWrap::DnsObject().GetServerName(),
  489. PVD_REC_SERVER_NAME);
  490. NewInst.SetProperty(
  491. ParentDomain.wstrZoneName,
  492. PVD_REC_CONTAINER_NAME);
  493. NewInst.SetProperty(
  494. ParentDomain.wstrNodeName,
  495. PVD_REC_DOMAIN_NAME);
  496. NewInst.SetProperty(
  497. wstrResultOwner,
  498. PVD_REC_OWNER_NAME);
  499. NewInst.SetProperty(
  500. pRec->GetTextRepresentation(wstrResultOwner),
  501. PVD_REC_TXT_REP);
  502. apRec->ConvertToWbemObject(NewInst);
  503. InstMgr.Indicate(NewInst.data());
  504. }
  505. }
  506. }
  507. return WBEM_S_NO_ERROR;
  508. }
  509. /////////////////////////////////////////////////////////////////////////////
  510. //++
  511. //
  512. // Description:
  513. // save this instance
  514. //
  515. // Arguments:
  516. // InstToPut [IN] WMI object to be saved
  517. // lFlags [IN] WMI flag
  518. // pCtx [IN] WMI context
  519. // pHandler [IN] WMI sink pointer
  520. //
  521. // Return Value:
  522. //
  523. //
  524. //--
  525. /////////////////////////////////////////////////////////////////////////////
  526. SCODE CDnsResourceRecord::PutInstance(
  527. IWbemClassObject * pInst ,
  528. long lFlags,
  529. IWbemContext* pCtx ,
  530. IWbemObjectSink * pHandler)
  531. {
  532. DWORD dwType;
  533. if(!pInst)
  534. {
  535. return WBEM_E_FAILED;
  536. }
  537. CDnsRpcRecord* pRecord = NULL;
  538. SCODE sc = CDnsRpcRecord::CreateClass(
  539. m_wType,
  540. (PVOID*) &pRecord);
  541. if (sc != S_OK)
  542. {
  543. return sc;
  544. }
  545. auto_ptr<CDnsRpcRecord> apRecord(pRecord);
  546. CWbemClassObject Inst(pInst);
  547. string strOwner;
  548. Inst.GetProperty(
  549. strOwner,
  550. PVD_REC_OWNER_NAME);
  551. string strRdata;
  552. Inst.GetProperty(
  553. strRdata,
  554. PVD_REC_RDATA);
  555. string strZone ;
  556. Inst.GetProperty(
  557. strZone,
  558. PVD_REC_CONTAINER_NAME);
  559. sc = apRecord->Init(
  560. strOwner,
  561. strRdata );
  562. if( FAILED ( sc ) )
  563. {
  564. return sc;
  565. }
  566. sc = apRecord->SendToServer(
  567. strZone.data(),
  568. CDnsRpcRecord::AddRecord);
  569. return WBEM_S_NO_ERROR;
  570. };
  571. /////////////////////////////////////////////////////////////////////////////
  572. //++
  573. //
  574. // Description:
  575. // delete the object specified in ObjectPath
  576. //
  577. // Arguments:
  578. // ObjectPath [IN] ObjPath for the instance to be deleted
  579. // lFlags [IN] WMI flag
  580. // pCtx [IN] WMI context
  581. // pHandler [IN] WMI sink pointer
  582. //
  583. // Return Value:
  584. // WBEM_S_NO_ERROR
  585. //
  586. //--
  587. /////////////////////////////////////////////////////////////////////////////
  588. SCODE CDnsResourceRecord::DeleteInstance(
  589. CObjPath & ObjectPath,
  590. long lFlags,
  591. IWbemContext * pCtx,
  592. IWbemObjectSink * pHandler)
  593. {
  594. CDnsRpcRecord* pRecord = NULL;
  595. // get Rdata
  596. wstring wstrRdata = ObjectPath.GetStringValueForProperty(
  597. PVD_REC_RDATA);
  598. string strRdata;
  599. WcharToString(wstrRdata.data(), strRdata);
  600. // get owner
  601. wstring wstrOwner = ObjectPath.GetStringValueForProperty(
  602. PVD_REC_OWNER_NAME);
  603. string strOwner;
  604. WcharToString(wstrOwner.data(), strOwner);
  605. SCODE sc = CDnsRpcRecord::CreateClass(
  606. m_wType,
  607. (PVOID*) &pRecord);
  608. if ( FAILED ( sc ) )
  609. {
  610. return sc;
  611. }
  612. auto_ptr<CDnsRpcRecord> apRecord(pRecord);
  613. string strZone;
  614. sc = apRecord->Init(
  615. strOwner,
  616. strRdata );
  617. if( FAILED(sc ) )
  618. {
  619. return sc;
  620. }
  621. wstring wstrContainer = ObjectPath.GetStringValueForProperty(
  622. PVD_REC_CONTAINER_NAME);
  623. string strContainer;
  624. WcharToString(wstrContainer.data(), strContainer);
  625. sc = apRecord->SendToServer(
  626. strContainer.data(),
  627. CDnsRpcRecord::DeleteRecord);
  628. return sc;
  629. }
  630. /////////////////////////////////////////////////////////////////////////////
  631. //++
  632. //
  633. // Description:
  634. // modify a record. for the given objpath, it tries to get the record first,
  635. // error out if not exist. Create new record based on pInArgs, error out if conflict
  636. // existing one. if success, delete old record.
  637. //
  638. // Arguments:
  639. // objPath [IN] point to record to be modified
  640. // pInArgs [IN] new property of a record to be modified to
  641. // pOutParams [IN] new object path after modify
  642. // pHandler [IN] wmi sink
  643. //
  644. // Return Value:
  645. // WBEM_S_NO_ERROR
  646. //
  647. //--
  648. /////////////////////////////////////////////////////////////////////////////
  649. SCODE
  650. CDnsResourceRecord::Modify(
  651. CObjPath& objPath,
  652. IWbemClassObject* pInArgs,
  653. IWbemClassObject* pOutParams,
  654. IWbemObjectSink* pHandler)
  655. {
  656. CDnsWrap& dns = CDnsWrap::DnsObject();
  657. //Get zonename
  658. wstring wstrZone = objPath.GetStringValueForProperty(
  659. PVD_REC_CONTAINER_NAME);
  660. if(wstrZone.empty())
  661. {
  662. return WBEM_E_INVALID_PARAMETER;
  663. }
  664. string strZone;
  665. WcharToString(wstrZone.data(), strZone);
  666. //Get owner
  667. wstring wstrOwner = objPath.GetStringValueForProperty(
  668. PVD_REC_OWNER_NAME);
  669. if(wstrOwner.empty())
  670. {
  671. return WBEM_E_INVALID_PARAMETER;
  672. }
  673. string strOwner;
  674. WcharToString(wstrOwner.data(), strOwner);
  675. //Get Rdata
  676. wstring wstrRdata = objPath.GetStringValueForProperty(
  677. PVD_REC_RDATA);
  678. if(wstrRdata.empty())
  679. {
  680. return WBEM_E_INVALID_PARAMETER;
  681. }
  682. string strRdata;
  683. WcharToString(wstrRdata.data(), strRdata);
  684. // create class
  685. CDnsRpcRecord* pRecord;
  686. SCODE sc = CDnsRpcRecord::CreateClass(
  687. m_wType,
  688. (PVOID*) &pRecord);
  689. if ( FAILED ( sc ) )
  690. {
  691. return sc;
  692. }
  693. auto_ptr<CDnsRpcRecord> apRec(pRecord);
  694. CWbemClassObject InstInArgs(pInArgs);
  695. sc = apRec->Init(
  696. m_wstrClassName,
  697. strOwner,
  698. strRdata,
  699. InstInArgs );
  700. if ( FAILED ( sc ) )
  701. {
  702. return sc;
  703. }
  704. apRec->SendToServer(
  705. strZone.data(),
  706. CDnsRpcRecord::AddRecord);
  707. // new record created, delete old one
  708. if ( apRec->RdataIsChanged())
  709. {
  710. try
  711. {
  712. CDnsRpcRecord* pOldRecord;
  713. sc = CDnsRpcRecord::CreateClass( m_wType, (PVOID*) &pOldRecord );
  714. if ( FAILED ( sc ) )
  715. {
  716. throw sc;
  717. }
  718. auto_ptr<CDnsRpcRecord> apOldRec(pOldRecord);
  719. sc = apOldRec->Init(
  720. strOwner,
  721. strRdata);
  722. if ( FAILED ( sc ) )
  723. {
  724. throw sc;
  725. }
  726. apOldRec->SendToServer(
  727. strZone.data(),
  728. CDnsRpcRecord::DeleteRecord);
  729. }
  730. catch(SCODE sc_e)
  731. {
  732. // if we fail to delete old record,
  733. // delete the one we just created
  734. apRec->SendToServer(
  735. strZone.data(),
  736. CDnsRpcRecord::DeleteRecord);
  737. return sc_e;
  738. }
  739. }
  740. //
  741. // set output
  742. //
  743. CObjPath newObjPath;
  744. apRec->GetObjectPath(
  745. dns.GetServerName(),
  746. wstrZone,
  747. L"",
  748. wstrOwner,
  749. newObjPath);
  750. CWbemClassObject instOutParams(pOutParams);
  751. instOutParams.SetProperty(
  752. newObjPath.GetObjectPathString(),
  753. PVD_MTH_REC_ARG_RR);
  754. return pHandler->Indicate(1, &instOutParams);
  755. }
  756. SCODE
  757. CDnsResourceRecord::GetDomainNameFromZoneAndOwner(
  758. string & InZone,
  759. string & InOwner,
  760. string & OutNode
  761. )
  762. {
  763. if( _stricmp( InOwner.c_str(), "@" ) == 0 )
  764. {
  765. OutNode = InZone;
  766. InOwner = InZone;
  767. }
  768. else if( _stricmp( InOwner.c_str(), InZone.c_str() ) == 0 )
  769. {
  770. OutNode = InZone;
  771. }
  772. else if( _wcsicmp( m_wstrClassName.c_str(), PVD_CLASS_RR_NS ) == 0 ) // NSType exception
  773. {
  774. OutNode = InOwner;
  775. }
  776. else {
  777. int posZone = InOwner.find( InZone, 0 );
  778. int posFirstPeriod = InOwner.find_first_of( '.' );
  779. string strtempZoneNode = InOwner.substr( posZone, InOwner.length() );
  780. string strtempPeriodNode = InOwner.substr( posFirstPeriod + 1, InOwner.length() );
  781. if( _stricmp( strtempZoneNode.c_str(), strtempPeriodNode.c_str() ) == 0 )
  782. {
  783. OutNode = strtempZoneNode;
  784. }
  785. else {
  786. OutNode = strtempPeriodNode;
  787. }
  788. }
  789. return WBEM_S_NO_ERROR;
  790. }
  791. /////////////////////////////////////////////////////////////////////////////
  792. //++
  793. //
  794. // Description:
  795. // get an instance of record based on record text representation
  796. //
  797. // Arguments:
  798. // pInArgs [IN] input args contains text rep of record
  799. // pOutParams [IN] output parameter
  800. // pHandler [IN] wmi sink
  801. //
  802. // Return Value:
  803. //
  804. //--
  805. /////////////////////////////////////////////////////////////////////////////
  806. SCODE
  807. CDnsResourceRecord::GetObjectFromText(
  808. IWbemClassObject * pInArgs,
  809. IWbemClassObject * pOutParams,
  810. IWbemObjectSink * pHandler
  811. )
  812. {
  813. // get zonename
  814. string strZone;
  815. CWbemClassObject InstInArgs(pInArgs);
  816. if(InstInArgs.GetProperty(
  817. strZone,
  818. PVD_MTH_REC_ARG_CONTAINER_NAME) != S_OK)
  819. {
  820. return WBEM_E_INVALID_PARAMETER;
  821. }
  822. //get textrepresentation
  823. string strTextRep;
  824. if(InstInArgs.GetProperty(
  825. strTextRep,
  826. PVD_MTH_REC_ARG_TEXTREP) != S_OK)
  827. {
  828. return WBEM_E_INVALID_PARAMETER;
  829. }
  830. // get OwnerName
  831. string strOwner;
  832. int pos = strTextRep.find(' ');
  833. if(pos != string::npos)
  834. {
  835. strOwner = strTextRep.substr(0, pos);
  836. }
  837. // get recordType
  838. pos = strTextRep.find_first_not_of(' ', pos); // move to record class
  839. pos = strTextRep.find_first_of(' ', pos);
  840. if(pos == string::npos)
  841. {
  842. return WBEM_E_INVALID_PARAMETER;
  843. }
  844. pos = strTextRep.find_first_not_of(' ', pos);
  845. int endpos = strTextRep.find(' ', pos); // move to record type
  846. if(endpos == string::npos)
  847. {
  848. return WBEM_E_INVALID_PARAMETER;
  849. }
  850. string strRecordType = strTextRep.substr(pos,endpos-pos);
  851. // set the record type
  852. m_wType = Dns_RecordTypeForName(
  853. (char*)strRecordType.data(),
  854. 0 // null terminated
  855. );
  856. // get Rdata
  857. pos = strTextRep.find_first_not_of(' ', endpos);
  858. string strRdata = strTextRep.substr(pos);
  859. string strNode = "";
  860. GetDomainNameFromZoneAndOwner(strZone, strOwner, strNode);
  861. //Form filter object
  862. CObjPath opFilter;
  863. opFilter.SetClass(PVD_CLASS_RESOURCERECORD);
  864. opFilter.AddProperty(PVD_REC_CONTAINER_NAME, strZone);
  865. opFilter.AddProperty(PVD_REC_DOMAIN_NAME, strNode);
  866. opFilter.AddProperty(PVD_REC_OWNER_NAME, strOwner);
  867. opFilter.AddProperty(PVD_REC_RDATA, strRdata);
  868. // get object
  869. return GetObject(
  870. opFilter,
  871. 0,
  872. 0,
  873. pHandler);
  874. }
  875. /////////////////////////////////////////////////////////////////////////////
  876. //++
  877. //
  878. // Description:
  879. // create an instance of record based on record text representation
  880. //
  881. // Arguments:
  882. // pInArgs [IN] input args contains text rep of record
  883. // pOutParams [IN] output parameter
  884. // pHandler [IN] wmi sink
  885. //
  886. // Return Value:
  887. //
  888. //--
  889. /////////////////////////////////////////////////////////////////////////////
  890. SCODE
  891. CDnsResourceRecord::CreateInstanceFromText(
  892. IWbemClassObject * pInArgs,
  893. IWbemClassObject * pOutParams,
  894. IWbemObjectSink * pHandler)
  895. {
  896. CDnsWrap& dns = CDnsWrap::DnsObject();
  897. // get zone name
  898. string strZone;
  899. CWbemClassObject InstInArgs(pInArgs);
  900. if( FAILED ( InstInArgs.GetProperty(
  901. strZone,
  902. PVD_MTH_REC_ARG_CONTAINER_NAME) ) )
  903. {
  904. return WBEM_E_INVALID_PARAMETER;
  905. }
  906. //get textrepresentation
  907. string strTextRep;
  908. if( FAILED ( InstInArgs.GetProperty(
  909. strTextRep,
  910. PVD_MTH_REC_ARG_TEXTREP) ) )
  911. {
  912. return WBEM_E_INVALID_PARAMETER;
  913. }
  914. // get OwnerName
  915. string strOwner;
  916. int pos = strTextRep.find(' ');
  917. if(pos != string::npos)
  918. {
  919. strOwner = strTextRep.substr(0, pos);
  920. }
  921. // get recordType
  922. // move to record class
  923. pos = strTextRep.find_first_not_of(' ', pos);
  924. pos = strTextRep.find_first_of(' ', pos);
  925. if(pos == string::npos)
  926. {
  927. return WBEM_E_INVALID_PARAMETER;
  928. }
  929. // move to record type
  930. pos = strTextRep.find_first_not_of(' ', pos);
  931. int endpos = strTextRep.find(' ', pos);
  932. if(endpos == string::npos)
  933. {
  934. return WBEM_E_INVALID_PARAMETER;
  935. }
  936. string strRecordType = strTextRep.substr(pos,endpos-pos);
  937. // get Rdata
  938. pos = strTextRep.find_first_not_of(' ', endpos);
  939. string strRdata = strTextRep.substr(pos);
  940. // set the record type
  941. m_wType = Dns_RecordTypeForName(
  942. (char*)strRecordType.data(),
  943. 0 // null terminated
  944. );
  945. // create class
  946. CDnsRpcRecord* pRecord;
  947. SCODE sc = CDnsRpcRecord::CreateClass(
  948. m_wType,
  949. (PVOID*) &pRecord);
  950. if ( FAILED ( sc ))
  951. {
  952. return sc;
  953. }
  954. auto_ptr<CDnsRpcRecord> apRecord(pRecord);
  955. sc = apRecord->Init(
  956. strOwner,
  957. strRdata
  958. );
  959. if ( FAILED ( sc ) )
  960. {
  961. return sc;
  962. }
  963. apRecord->SendToServer(
  964. strZone.data(),
  965. CDnsRpcRecord::AddRecord);
  966. // set output parameter
  967. CObjPath newObjPath;
  968. apRecord->GetObjectPath(
  969. dns.GetServerName(),
  970. CharToWstring(strZone.data(), strZone.length()),
  971. L"",
  972. CharToWstring(strOwner.data(), strOwner.length()),
  973. newObjPath );
  974. CWbemClassObject instOutParams( pOutParams );
  975. instOutParams.SetProperty(
  976. newObjPath.GetObjectPathString(),
  977. PVD_MTH_REC_ARG_RR);
  978. return pHandler->Indicate(1, &instOutParams);
  979. //done
  980. }
  981. /////////////////////////////////////////////////////////////////////////////
  982. //++
  983. //
  984. // Description:
  985. // create an instance of record based on input parameter
  986. // with proper property setting
  987. //
  988. // Arguments:
  989. // pInArgs [IN] input args contains property setting
  990. // pOutParams [IN] output parameter
  991. // pHandler [IN] wmi sink
  992. //
  993. // Return Value:
  994. //
  995. //--
  996. /////////////////////////////////////////////////////////////////////////////
  997. SCODE
  998. CDnsResourceRecord::CreateInstanceFromProperty(
  999. IWbemClassObject * pInArgs,
  1000. IWbemClassObject * pOutParams,
  1001. IWbemObjectSink * pHandler
  1002. )
  1003. {
  1004. CDnsWrap& dns = CDnsWrap::DnsObject();
  1005. CWbemClassObject InstInArgs(pInArgs);
  1006. string strZone;
  1007. // get zone name
  1008. if( FAILED ( InstInArgs.GetProperty(
  1009. strZone,
  1010. PVD_REC_CONTAINER_NAME) ) )
  1011. {
  1012. return WBEM_E_INVALID_PARAMETER;
  1013. }
  1014. // get owner name
  1015. string strOwner;
  1016. if( FAILED ( InstInArgs.GetProperty(
  1017. strOwner,
  1018. PVD_REC_OWNER_NAME) ) )
  1019. {
  1020. return WBEM_E_INVALID_PARAMETER;
  1021. }
  1022. string strRdata;
  1023. // create class
  1024. CDnsRpcRecord* pRecord;
  1025. SCODE sc = CDnsRpcRecord::CreateClass(
  1026. m_wType,
  1027. (PVOID*) &pRecord);
  1028. if ( FAILED( sc ) )
  1029. {
  1030. return sc;
  1031. }
  1032. auto_ptr<CDnsRpcRecord> apRecord(pRecord);
  1033. sc = apRecord->Init(
  1034. m_wstrClassName,
  1035. strOwner,
  1036. strRdata,
  1037. InstInArgs
  1038. );
  1039. if ( FAILED ( sc ) )
  1040. {
  1041. return sc;
  1042. }
  1043. apRecord->SendToServer(
  1044. strZone.data(),
  1045. CDnsRpcRecord::AddRecord);
  1046. // set output parameter
  1047. CObjPath newObjPath;
  1048. apRecord->GetObjectPath(
  1049. dns.GetServerName(),
  1050. CharToWstring(strZone.data(),strZone.length()),
  1051. L"",
  1052. CharToWstring(strOwner.data(), strOwner.length()),
  1053. newObjPath);
  1054. CWbemClassObject instOutParams(pOutParams);
  1055. instOutParams.SetProperty(
  1056. newObjPath.GetObjectPathString(),
  1057. PVD_MTH_REC_ARG_RR);
  1058. return pHandler->Indicate(1, &instOutParams);
  1059. }
  1060. /////////////////////////////////////////////////////////////////////////////
  1061. //++
  1062. //
  1063. // Description:
  1064. // enum instances of dns domain
  1065. //
  1066. // Arguments:
  1067. // pSqlEval [IN] pointer to CSqlEval object that implements
  1068. // logic based on sql language to filter
  1069. // which instance should be send to wmi
  1070. // not used here
  1071. // lFlags [IN] WMI flag
  1072. // pCtx [IN] WMI context
  1073. // pHandler [IN] WMI sink pointer
  1074. //
  1075. // Return Value:
  1076. // WBEM_S_NO_ERROR
  1077. //
  1078. //--
  1079. /////////////////////////////////////////////////////////////////////////////
  1080. SCODE CDnsResourceRecord::ExecQuery(
  1081. CSqlEval * pSqlEval,
  1082. long lFlags,
  1083. IWbemContext * pCtx,
  1084. IWbemObjectSink * pHandler
  1085. )
  1086. {
  1087. SCODE sc = WBEM_S_NO_ERROR;
  1088. const WCHAR * ppName[] =
  1089. {
  1090. PVD_REC_CONTAINER_NAME,
  1091. PVD_REC_DOMAIN_NAME,
  1092. PVD_REC_OWNER_NAME
  1093. };
  1094. if (pSqlEval == NULL)
  1095. {
  1096. return WBEM_E_INVALID_PARAMETER;
  1097. }
  1098. //
  1099. // converting from sql to a set of zone, domain and owner name to be queried on
  1100. //
  1101. CQueryEnumerator qeInst(
  1102. (WCHAR**) ppName,
  1103. 3);
  1104. pSqlEval->GenerateQueryEnum(qeInst);
  1105. qeInst.Reset();
  1106. BOOL flag = TRUE;
  1107. CWbemInstanceMgr InstanceMgr(
  1108. pHandler);
  1109. CDnsWrap& dns = CDnsWrap::DnsObject();
  1110. //
  1111. // loop through a array of ppName, figure out what zone, domain and owner
  1112. // criteria should be used, then call dnsEnumRecordsForDomainEx with those
  1113. // parameter plus CSqlEval, CSqlEval is used further to filter out record
  1114. //
  1115. while(flag)
  1116. {
  1117. int nSize;
  1118. const WCHAR **pp = qeInst.GetNext(nSize);
  1119. if(pp != NULL)
  1120. {
  1121. // if no domain specified, do recursive search
  1122. BOOL bRecursive = (pp[1] == NULL);
  1123. //if zone not specified, enum all zones
  1124. if(pp[0] == NULL)
  1125. {
  1126. list<CDomainNode> objList;
  1127. sc = dns.dnsEnumDomainForServer(&objList);
  1128. list<CDomainNode>::iterator i;
  1129. for(i=objList.begin(); i!=objList.end(); ++i)
  1130. {
  1131. //if(_wcsicmp(i->wstrZoneName.data(), PVD_DNS_ROOTHINTS)==0)
  1132. // i->wstrNodeName = i->wstrZoneName;
  1133. if(pp[1] != NULL)
  1134. {
  1135. i->wstrNodeName = pp[1];
  1136. if(pp[2] != NULL)
  1137. {
  1138. //take only name ifself, not FQDN
  1139. i->wstrChildName = pp[2];
  1140. int pos = i->wstrChildName.find_first_of('.',0);
  1141. if(pos != string::npos)
  1142. i->wstrChildName = i->wstrChildName.substr(0,pos);
  1143. }
  1144. }
  1145. try
  1146. {
  1147. sc = dns.dnsEnumRecordsForDomainEx(
  1148. *i,
  1149. pSqlEval,
  1150. &QueryFilter,
  1151. bRecursive,
  1152. m_wType,
  1153. DNS_RPC_VIEW_ALL_DATA,
  1154. m_pClass,
  1155. InstanceMgr);
  1156. }
  1157. catch(CDnsProvException e)
  1158. {
  1159. if(e.GetErrorCode() != DNS_ERROR_NAME_DOES_NOT_EXIST)
  1160. throw;
  1161. }
  1162. }
  1163. }
  1164. else
  1165. {
  1166. CDomainNode node;
  1167. if(pp[2] != NULL)
  1168. {
  1169. //take only name ifself, not FQDN
  1170. if( pp[1] != NULL)
  1171. {
  1172. node.wstrChildName = pp[2];
  1173. int pos = node.wstrChildName.find_first_of('.',0);
  1174. if(pos != string::npos)
  1175. node.wstrChildName = node.wstrChildName.substr(0,pos);
  1176. }
  1177. }
  1178. node.wstrZoneName = pp[0];
  1179. if(pp[1] != NULL)
  1180. {
  1181. if ( _wcsicmp( pp[0], PVD_DNS_ROOTHINTS) != 0 &&
  1182. _wcsicmp ( pp[0], PVD_DNS_CACHE ) != 0 )
  1183. {
  1184. node.wstrNodeName = pp[1];
  1185. }
  1186. }
  1187. else
  1188. {
  1189. if ( _wcsicmp( pp[0], PVD_DNS_ROOTHINTS) != 0 &&
  1190. _wcsicmp ( pp[0], PVD_DNS_CACHE ) != 0 )
  1191. {
  1192. node.wstrNodeName = pp[0];
  1193. }
  1194. }
  1195. sc = dns.dnsEnumRecordsForDomainEx(
  1196. node,
  1197. pSqlEval,
  1198. &QueryFilter,
  1199. bRecursive,
  1200. m_wType,
  1201. DNS_RPC_VIEW_ALL_DATA,
  1202. m_pClass,
  1203. InstanceMgr);
  1204. }
  1205. }
  1206. else
  1207. {
  1208. flag = FALSE;
  1209. }
  1210. }
  1211. return S_OK;
  1212. }