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.

1183 lines
24 KiB

  1. /*++
  2. Copyright (c) 1997-2001 Microsoft Corporation
  3. Module Name:
  4. rrcopy.c
  5. Abstract:
  6. Domain Name System (DNS) Library
  7. Copy resource record routines.
  8. Author:
  9. Jim Gilroy (jamesg) February, 1997
  10. Revision History:
  11. --*/
  12. #include "local.h"
  13. PDNS_RECORD
  14. ARecordCopy(
  15. IN PDNS_RECORD pRR,
  16. IN DNS_CHARSET CharSetIn,
  17. IN DNS_CHARSET CharSetOut
  18. )
  19. /*++
  20. Routine Description:
  21. Copy A record data from packet.
  22. Arguments:
  23. pRR - RR to copy
  24. Return Value:
  25. Ptr to new record if successful.
  26. NULL on failure.
  27. --*/
  28. {
  29. PDNS_RECORD precord;
  30. precord = Dns_AllocateRecord( sizeof(IP4_ADDRESS) );
  31. if ( !precord )
  32. {
  33. return NULL;
  34. }
  35. precord->Data.A.IpAddress = pRR->Data.A.IpAddress;
  36. return precord;
  37. }
  38. PDNS_RECORD
  39. PtrRecordCopy(
  40. IN PDNS_RECORD pRR,
  41. IN DNS_CHARSET CharSetIn,
  42. IN DNS_CHARSET CharSetOut
  43. )
  44. /*++
  45. Routine Description:
  46. Copy PTR compatible record.
  47. Includes: NS, PTR, CNAME, MB, MR, MG, MD, MF
  48. Arguments:
  49. pRR - RR to copy
  50. Return Value:
  51. Ptr to new record if successful.
  52. NULL on failure.
  53. --*/
  54. {
  55. PDNS_RECORD precord;
  56. precord = Dns_AllocateRecord( sizeof( DNS_PTR_DATA ) );
  57. if ( !precord )
  58. {
  59. return NULL;
  60. }
  61. precord->Data.PTR.pNameHost = Dns_NameCopyAllocate(
  62. pRR->Data.PTR.pNameHost,
  63. 0, // length unknown
  64. CharSetIn,
  65. CharSetOut
  66. );
  67. if ( ! precord->Data.PTR.pNameHost )
  68. {
  69. FREE_HEAP( precord );
  70. return NULL;
  71. }
  72. FLAG_FreeData( precord ) = TRUE;
  73. return precord;
  74. }
  75. PDNS_RECORD
  76. SoaRecordCopy(
  77. IN PDNS_RECORD pRR,
  78. IN DNS_CHARSET CharSetIn,
  79. IN DNS_CHARSET CharSetOut
  80. )
  81. /*++
  82. Routine Description:
  83. Copy SOA record.
  84. Arguments:
  85. pRR - RR to copy
  86. Return Value:
  87. Ptr to new record if successful.
  88. NULL on failure.
  89. --*/
  90. {
  91. PDNS_RECORD precord;
  92. LPSTR pname;
  93. precord = Dns_AllocateRecord( sizeof( DNS_SOA_DATA ) );
  94. if ( !precord )
  95. {
  96. return NULL;
  97. }
  98. //
  99. // copy integer data
  100. //
  101. memcpy(
  102. & precord->Data.SOA.dwSerialNo,
  103. & pRR->Data.SOA.dwSerialNo,
  104. SIZEOF_SOA_FIXED_DATA );
  105. //
  106. // create copy of primary and admin
  107. //
  108. pname = Dns_NameCopyAllocate(
  109. pRR->Data.SOA.pNamePrimaryServer,
  110. 0, // length unknown
  111. CharSetIn,
  112. CharSetOut
  113. );
  114. if ( !pname )
  115. {
  116. FREE_HEAP( precord );
  117. return NULL;
  118. }
  119. precord->Data.SOA.pNamePrimaryServer = pname;
  120. pname = Dns_NameCopyAllocate(
  121. pRR->Data.SOA.pNameAdministrator,
  122. 0, // length unknown
  123. CharSetIn,
  124. CharSetOut
  125. );
  126. if ( !pname )
  127. {
  128. FREE_HEAP( precord->Data.SOA.pNamePrimaryServer );
  129. FREE_HEAP( precord );
  130. return NULL;
  131. }
  132. precord->Data.SOA.pNameAdministrator = pname;
  133. FLAG_FreeData( precord ) = TRUE;
  134. return precord;
  135. }
  136. PDNS_RECORD
  137. MinfoRecordCopy(
  138. IN PDNS_RECORD pRR,
  139. IN DNS_CHARSET CharSetIn,
  140. IN DNS_CHARSET CharSetOut
  141. )
  142. /*++
  143. Routine Description:
  144. Copy MINFO and RP records from wire.
  145. Arguments:
  146. pRR - RR to copy
  147. Return Value:
  148. Ptr to new record if successful.
  149. NULL on failure.
  150. --*/
  151. {
  152. PDNS_RECORD precord;
  153. LPSTR pname;
  154. precord = Dns_AllocateRecord( sizeof( DNS_MINFO_DATA ) );
  155. if ( !precord )
  156. {
  157. return NULL;
  158. }
  159. //
  160. // create copy of name fields
  161. //
  162. pname = Dns_NameCopyAllocate(
  163. pRR->Data.MINFO.pNameMailbox,
  164. 0, // length unknown
  165. CharSetIn,
  166. CharSetOut
  167. );
  168. if ( !pname )
  169. {
  170. FREE_HEAP( precord );
  171. return NULL;
  172. }
  173. precord->Data.MINFO.pNameMailbox = pname;
  174. pname = Dns_NameCopyAllocate(
  175. pRR->Data.MINFO.pNameErrorsMailbox,
  176. 0, // length unknown
  177. CharSetIn,
  178. CharSetOut
  179. );
  180. if ( !pname )
  181. {
  182. FREE_HEAP( precord->Data.MINFO.pNameMailbox );
  183. FREE_HEAP( precord );
  184. return NULL;
  185. }
  186. precord->Data.MINFO.pNameErrorsMailbox = pname;
  187. FLAG_FreeData( precord ) = TRUE;
  188. return precord;
  189. }
  190. PDNS_RECORD
  191. MxRecordCopy(
  192. IN PDNS_RECORD pRR,
  193. IN DNS_CHARSET CharSetIn,
  194. IN DNS_CHARSET CharSetOut
  195. )
  196. /*++
  197. Routine Description:
  198. Copy MX compatible record from wire.
  199. Includes: MX, RT, AFSDB
  200. Arguments:
  201. pRR - RR to copy
  202. Return Value:
  203. Ptr to new record if successful.
  204. NULL on failure.
  205. --*/
  206. {
  207. PDNS_RECORD precord;
  208. PCHAR pname;
  209. precord = Dns_AllocateRecord( sizeof( DNS_MX_DATA ) );
  210. if ( !precord )
  211. {
  212. return NULL;
  213. }
  214. // MX preference value
  215. // RT preference
  216. // AFSDB subtype
  217. precord->Data.MX.wPreference = pRR->Data.MX.wPreference;
  218. // MX exchange
  219. // RT exchange
  220. // AFSDB hostname
  221. // - name immediately follows MX data struct
  222. pname = Dns_NameCopyAllocate(
  223. pRR->Data.MX.pNameExchange,
  224. 0, // length unknown
  225. CharSetIn,
  226. CharSetOut
  227. );
  228. if ( !pname )
  229. {
  230. FREE_HEAP( precord );
  231. return NULL;
  232. }
  233. precord->Data.MX.pNameExchange = pname;
  234. FLAG_FreeData( precord ) = TRUE;
  235. return precord;
  236. }
  237. PDNS_RECORD
  238. TxtRecordCopy(
  239. IN PDNS_RECORD pRR,
  240. IN DNS_CHARSET CharSetIn,
  241. IN DNS_CHARSET CharSetOut
  242. )
  243. /*++
  244. Routine Description:
  245. Copy TXT compatible records.
  246. Includes: TXT, X25, HINFO, ISDN
  247. Arguments:
  248. pRR - RR to copy
  249. Return Value:
  250. Ptr to new record if successful.
  251. NULL on failure.
  252. --*/
  253. {
  254. PDNS_RECORD precord;
  255. WORD bufLength = sizeof( DNS_TXT_DATA );
  256. INT count = pRR->Data.TXT.dwStringCount;
  257. LPSTR * ppstringIn;
  258. LPSTR * ppstringNew;
  259. LPSTR pstring;
  260. bufLength += (WORD)(sizeof(LPSTR) * count);
  261. precord = Dns_AllocateRecord( bufLength );
  262. if ( !precord )
  263. {
  264. return NULL;
  265. }
  266. precord->Data.TXT.dwStringCount = 0;
  267. //
  268. // copy each string
  269. // - first string written immediately after string ptr list
  270. // - each string written immediately after previous
  271. //
  272. ppstringIn = (LPSTR *) pRR->Data.TXT.pStringArray;
  273. ppstringNew = (LPSTR *) precord->Data.TXT.pStringArray;
  274. FLAG_FreeData( precord ) = TRUE;
  275. while ( count-- )
  276. {
  277. pstring = Dns_StringCopyAllocate(
  278. *ppstringIn,
  279. 0, // length unknown
  280. CharSetIn,
  281. CharSetOut
  282. );
  283. if ( ! pstring )
  284. {
  285. Dns_RecordFree( precord );
  286. return NULL;
  287. }
  288. *ppstringNew = pstring;
  289. precord->Data.TXT.dwStringCount += 1;
  290. ppstringIn++;
  291. ppstringNew++;
  292. }
  293. return precord;
  294. }
  295. PDNS_RECORD
  296. FlatRecordCopy(
  297. IN PDNS_RECORD pRR,
  298. IN DNS_CHARSET CharSetIn,
  299. IN DNS_CHARSET CharSetOut
  300. )
  301. /*++
  302. Routine Description:
  303. Copy flat data compatible record.
  304. Includes: AAAA
  305. Arguments:
  306. pRR - RR to copy
  307. Return Value:
  308. Ptr to new record if successful.
  309. NULL on failure.
  310. --*/
  311. {
  312. PDNS_RECORD precord;
  313. //
  314. // allocate given datalength
  315. //
  316. precord = Dns_AllocateRecord( pRR->wDataLength );
  317. if ( !precord )
  318. {
  319. return( NULL );
  320. }
  321. //
  322. // flat copy of data
  323. //
  324. memcpy(
  325. & precord->Data,
  326. & pRR->Data,
  327. pRR->wDataLength );
  328. return( precord );
  329. }
  330. PDNS_RECORD
  331. SrvRecordCopy(
  332. IN PDNS_RECORD pRR,
  333. IN DNS_CHARSET CharSetIn,
  334. IN DNS_CHARSET CharSetOut
  335. )
  336. /*++
  337. Routine Description:
  338. Copy SRV compatible record from wire.
  339. Includes: SRV, RT, AFSDB
  340. Arguments:
  341. pRR - RR to copy
  342. Return Value:
  343. Ptr to new record if successful.
  344. NULL on failure.
  345. --*/
  346. {
  347. PDNS_RECORD precord;
  348. PCHAR pname;
  349. precord = Dns_AllocateRecord( sizeof( DNS_SRV_DATA ) );
  350. if ( !precord )
  351. {
  352. return NULL;
  353. }
  354. // copy integer data
  355. precord->Data.SRV.wPriority = pRR->Data.SRV.wPriority;
  356. precord->Data.SRV.wWeight = pRR->Data.SRV.wWeight;
  357. precord->Data.SRV.wPort = pRR->Data.SRV.wPort;
  358. // copy target name
  359. pname = Dns_NameCopyAllocate(
  360. pRR->Data.SRV.pNameTarget,
  361. 0, // length unknown
  362. CharSetIn,
  363. CharSetOut
  364. );
  365. if ( !pname )
  366. {
  367. FREE_HEAP( precord );
  368. return NULL;
  369. }
  370. precord->Data.SRV.pNameTarget = pname;
  371. SET_FREE_DATA( precord );
  372. return precord;
  373. }
  374. PDNS_RECORD
  375. AtmaRecordCopy(
  376. IN PDNS_RECORD pRR,
  377. IN DNS_CHARSET CharSetIn,
  378. IN DNS_CHARSET CharSetOut
  379. )
  380. /*++
  381. Routine Description:
  382. Copy Atma compatible record from wire.
  383. Includes:
  384. Arguments:
  385. pRR - RR to copy
  386. Return Value:
  387. Ptr to new record if successful.
  388. NULL on failure.
  389. --*/
  390. {
  391. PDNS_RECORD precord;
  392. WORD bufLength;
  393. //
  394. // determine required buffer length and allocate
  395. //
  396. bufLength = sizeof(DNS_ATMA_DATA) + DNS_ATMA_MAX_ADDR_LENGTH ;
  397. precord = Dns_AllocateRecord( bufLength );
  398. if ( !precord )
  399. {
  400. return( NULL );
  401. }
  402. // copy integer data
  403. precord->Data.ATMA.AddressType = pRR->Data.ATMA.AddressType;
  404. if ( precord->Data.ATMA.AddressType == DNS_ATMA_FORMAT_E164 )
  405. {
  406. precord->wDataLength = (WORD) strlen(pRR->Data.ATMA.Address);
  407. if ( precord->wDataLength > DNS_ATMA_MAX_ADDR_LENGTH )
  408. {
  409. precord->wDataLength = DNS_ATMA_MAX_ADDR_LENGTH;
  410. }
  411. strncpy(
  412. precord->Data.ATMA.Address,
  413. pRR->Data.ATMA.Address,
  414. precord->wDataLength );
  415. }
  416. else
  417. {
  418. precord->wDataLength = DNS_ATMA_MAX_ADDR_LENGTH;
  419. memcpy(
  420. precord->Data.ATMA.Address,
  421. pRR->Data.ATMA.Address,
  422. precord->wDataLength );
  423. }
  424. return( precord );
  425. }
  426. PDNS_RECORD
  427. WinsrRecordCopy(
  428. IN PDNS_RECORD pRR,
  429. IN DNS_CHARSET CharSetIn,
  430. IN DNS_CHARSET CharSetOut
  431. )
  432. /*++
  433. Routine Description:
  434. Copy WINSR compatible record.
  435. Arguments:
  436. pRR - RR to copy
  437. Return Value:
  438. Ptr to new record if successful.
  439. NULL on failure.
  440. --*/
  441. {
  442. PDNS_RECORD precord;
  443. PSTR pname;
  444. //
  445. // determine required buffer length and allocate
  446. //
  447. precord = Dns_AllocateRecord( sizeof(DNS_WINSR_DATA) );
  448. if ( !precord )
  449. {
  450. return NULL;
  451. }
  452. // allocate name copy
  453. pname = Dns_NameCopyAllocate(
  454. pRR->Data.WINSR.pNameResultDomain,
  455. 0, // length unknown
  456. CharSetIn,
  457. CharSetOut
  458. );
  459. if ( !pname )
  460. {
  461. FREE_HEAP( precord );
  462. return NULL;
  463. }
  464. // fill record fields
  465. precord->Data.WINSR.pNameResultDomain = pname;
  466. precord->Data.WINSR.dwMappingFlag = pRR->Data.WINSR.dwMappingFlag;
  467. precord->Data.WINSR.dwLookupTimeout = pRR->Data.WINSR.dwLookupTimeout;
  468. precord->Data.WINSR.dwCacheTimeout = pRR->Data.WINSR.dwCacheTimeout;
  469. FLAG_FreeData( precord ) = TRUE;
  470. return precord;
  471. }
  472. //
  473. // RR copy jump table
  474. //
  475. typedef PDNS_RECORD (* RR_COPY_FUNCTION)(
  476. PDNS_RECORD,
  477. DNS_CHARSET,
  478. DNS_CHARSET );
  479. // extern RR_COPY_FUNCTION RRCopyTable[];
  480. RR_COPY_FUNCTION RRCopyTable[] =
  481. {
  482. NULL, // ZERO
  483. ARecordCopy, // A
  484. PtrRecordCopy, // NS
  485. PtrRecordCopy, // MD
  486. PtrRecordCopy, // MF
  487. PtrRecordCopy, // CNAME
  488. SoaRecordCopy, // SOA
  489. PtrRecordCopy, // MB
  490. PtrRecordCopy, // MG
  491. PtrRecordCopy, // MR
  492. NULL, // NULL
  493. NULL, //WksRecordCopy, // WKS
  494. PtrRecordCopy, // PTR
  495. TxtRecordCopy, // HINFO
  496. MinfoRecordCopy, // MINFO
  497. MxRecordCopy, // MX
  498. TxtRecordCopy, // TXT
  499. MinfoRecordCopy, // RP
  500. MxRecordCopy, // AFSDB
  501. TxtRecordCopy, // X25
  502. TxtRecordCopy, // ISDN
  503. MxRecordCopy, // RT
  504. NULL, // NSAP
  505. NULL, // NSAPPTR
  506. NULL, // SIG
  507. NULL, // KEY
  508. NULL, // PX
  509. NULL, // GPOS
  510. FlatRecordCopy, // AAAA
  511. NULL, // LOC
  512. NULL, // NXT
  513. NULL, // EID
  514. NULL, // NIMLOC
  515. SrvRecordCopy, // SRV
  516. AtmaRecordCopy, // ATMA
  517. NULL, // NAPTR
  518. NULL, // KX
  519. NULL, // CERT
  520. NULL, // A6
  521. NULL, // DNAME
  522. NULL, // SINK
  523. NULL, // OPT
  524. NULL, // 42
  525. NULL, // 43
  526. NULL, // 44
  527. NULL, // 45
  528. NULL, // 46
  529. NULL, // 47
  530. NULL, // 48
  531. //
  532. // NOTE: last type indexed by type ID MUST be set
  533. // as MAX_SELF_INDEXED_TYPE #define in record.h
  534. // (see note above in record info table)
  535. //
  536. // Pseudo record types
  537. //
  538. NULL, // TKEY
  539. NULL, // TSIG
  540. //
  541. // MS only types
  542. //
  543. FlatRecordCopy, // WINS
  544. WinsrRecordCopy, // WINSR
  545. };
  546. //
  547. // Generic copy functions
  548. //
  549. PDNS_RECORD
  550. privateRecordCopy(
  551. IN PDNS_RECORD pRecord,
  552. IN PDNS_RECORD pPrevIn,
  553. IN PDNS_RECORD pPrevCopy,
  554. IN DNS_CHARSET CharSetIn,
  555. IN DNS_CHARSET CharSetOut
  556. )
  557. /*++
  558. Routine Description:
  559. Copy record to as member of record set.
  560. The previous records allow suppression of owner name copy when copying
  561. RR set.
  562. Arguments:
  563. pRecord - record to copy
  564. pPrevIn - previous incoming record copied
  565. pPrevCopy - copy of pPrevIn in new set
  566. CharSetIn - input record character set; OPTIONAL
  567. if zero, pRecord must have CharSet;
  568. if non-zero, pRecord must have zero or matching CharSet;
  569. allow this to be specified independently of pRecord, to handle
  570. conversion of user supplied records, which we do not want to
  571. modify
  572. CharSetOut - desired record character set
  573. Return Value:
  574. Ptr to copy of record in desired character set.
  575. NULL on error.
  576. --*/
  577. {
  578. PDNS_RECORD prr;
  579. WORD index;
  580. DNS_CHARSET recordCharSet;
  581. DNSDBG( TRACE, ( "privateRecordCopy( %p )\n", pRecord ));
  582. //
  583. // input character set
  584. // allow specification of input character set to handle case
  585. // of user created records, but if input record has a set
  586. // then it's assumed to be valid
  587. // so validity check:
  588. // - CharSetIn == 0 => use record's != 0 set
  589. // - record's set == 0 => use CharSetIn != 0
  590. // - CharSetIn == record's set
  591. //
  592. recordCharSet = RECORD_CHARSET( pRecord );
  593. if ( recordCharSet )
  594. {
  595. ASSERT( CharSetIn == 0 || CharSetIn == recordCharSet );
  596. CharSetIn = recordCharSet;
  597. }
  598. else // record has no charset
  599. {
  600. if ( CharSetIn == 0 )
  601. {
  602. ASSERT( FALSE );
  603. goto Failed;
  604. }
  605. }
  606. //
  607. // copy record data
  608. //
  609. if ( pRecord->wDataLength != 0 )
  610. {
  611. index = INDEX_FOR_TYPE( pRecord->wType );
  612. DNS_ASSERT( index <= MAX_RECORD_TYPE_INDEX );
  613. if ( !index || !RRCopyTable[ index ] )
  614. {
  615. DNS_PRINT((
  616. "WARNING: No copy routine for type = %d\n"
  617. "\tdoing flat copy of record at %p\n",
  618. pRecord->wType,
  619. pRecord ));
  620. prr = FlatRecordCopy(
  621. pRecord,
  622. CharSetIn,
  623. CharSetOut );
  624. }
  625. else
  626. {
  627. prr = RRCopyTable[ index ](
  628. pRecord,
  629. CharSetIn,
  630. CharSetOut );
  631. }
  632. }
  633. else // no data record
  634. {
  635. prr = FlatRecordCopy(
  636. pRecord,
  637. CharSetIn,
  638. CharSetOut );
  639. }
  640. if ( !prr )
  641. {
  642. goto Failed;
  643. }
  644. //
  645. // copy record structure fields
  646. // - type
  647. // - TTL
  648. // - flags
  649. //
  650. prr->dwTtl = pRecord->dwTtl;
  651. prr->wType = pRecord->wType;
  652. prr->Flags.S.Section = pRecord->Flags.S.Section;
  653. prr->Flags.S.Delete = pRecord->Flags.S.Delete;
  654. prr->Flags.S.CharSet = CharSetOut;
  655. //
  656. // copy name
  657. //
  658. if ( pRecord->pName )
  659. {
  660. //
  661. // - if incoming name has FreeOwner set, then always copy
  662. // as never know when incoming set will be tossed
  663. //
  664. // - then check if incoming name same as previous incoming
  665. // name in which case we can use previous copied name
  666. //
  667. // - otherwise full copy of name
  668. //
  669. if ( !FLAG_FreeOwner( pRecord ) &&
  670. pPrevIn && pPrevCopy &&
  671. pRecord->pName == pPrevIn->pName )
  672. {
  673. prr->pName = pPrevCopy->pName;
  674. }
  675. else
  676. {
  677. prr->pName = Dns_NameCopyAllocate(
  678. pRecord->pName,
  679. 0, // unknown length
  680. CharSetIn,
  681. CharSetOut
  682. );
  683. if ( !prr->pName )
  684. {
  685. FREE_HEAP( prr );
  686. goto Failed;
  687. }
  688. FLAG_FreeOwner( prr ) = TRUE;
  689. }
  690. }
  691. DNSDBG( TRACE, (
  692. "Leaving privateRecordCopy(%p) = %p.\n",
  693. pRecord,
  694. prr ));
  695. return( prr );
  696. Failed:
  697. DNSDBG( TRACE, (
  698. "privateRecordCopy(%p) failed\n",
  699. pRecord ));
  700. return( NULL );
  701. }
  702. PDNS_RECORD
  703. WINAPI
  704. Dns_RecordCopyEx(
  705. IN PDNS_RECORD pRecord,
  706. IN DNS_CHARSET CharSetIn,
  707. IN DNS_CHARSET CharSetOut
  708. )
  709. /*++
  710. Routine Description:
  711. Copy record.
  712. Arguments:
  713. pRecord - record to copy
  714. CharSetIn - incoming record's character set
  715. CharSetOut -- char set for resulting record
  716. Return Value:
  717. Ptr to copy of record in desired character set.
  718. NULL on error.
  719. --*/
  720. {
  721. DNSDBG( TRACE, ( "Dns_RecordCopyEx( %p )\n", pRecord ));
  722. //
  723. // call private copy routine
  724. // - set optional ptrs to cause full owner name copy
  725. //
  726. return privateRecordCopy(
  727. pRecord,
  728. NULL,
  729. NULL,
  730. CharSetIn,
  731. CharSetOut );
  732. }
  733. PDNS_RECORD
  734. WINAPI
  735. Dns_RecordCopy_W(
  736. IN PDNS_RECORD pRecord
  737. )
  738. /*++
  739. Routine Description:
  740. Copy record.
  741. Arguments:
  742. pRecord - unicode record to copy to unicode
  743. Return Value:
  744. Ptr to copy of record in desired character set.
  745. NULL on error.
  746. --*/
  747. {
  748. DNSDBG( TRACE, ( "Dns_RecordCopy( %p )\n", pRecord ));
  749. //
  750. // call private copy routine
  751. // - set optional ptrs to cause full owner name copy
  752. //
  753. return privateRecordCopy(
  754. pRecord,
  755. NULL,
  756. NULL,
  757. DnsCharSetUnicode,
  758. DnsCharSetUnicode );
  759. }
  760. PDNS_RECORD
  761. WINAPI
  762. Dns_RecordCopy_A(
  763. IN PDNS_RECORD pRecord
  764. )
  765. /*++
  766. Routine Description:
  767. Copy record.
  768. Arguments:
  769. pRecord - ANSI record to copy to ANSI
  770. Return Value:
  771. Ptr to copy of record in desired character set.
  772. NULL on error.
  773. --*/
  774. {
  775. DNSDBG( TRACE, ( "Dns_RecordCopy( %p )\n", pRecord ));
  776. //
  777. // call private copy routine
  778. // - set optional ptrs to cause full owner name copy
  779. //
  780. return privateRecordCopy(
  781. pRecord,
  782. NULL,
  783. NULL,
  784. DnsCharSetAnsi,
  785. DnsCharSetAnsi );
  786. }
  787. //
  788. // Record set copy
  789. //
  790. PDNS_RECORD
  791. Dns_RecordSetCopyEx(
  792. IN PDNS_RECORD pRR,
  793. IN DNS_CHARSET CharSetIn,
  794. IN DNS_CHARSET CharSetOut
  795. )
  796. /*++
  797. Routine Description:
  798. Copy record set, converting to UTF8 if necessary.
  799. Arguments:
  800. pRR - incoming record set
  801. CharSetIn - incoming record's character set
  802. CharSetOut -- char set for resulting record
  803. Return Value:
  804. Ptr to new record set, if successful.
  805. NULL on error.
  806. --*/
  807. {
  808. return Dns_RecordListCopyEx(
  809. pRR,
  810. 0, // no screening flags
  811. CharSetIn,
  812. CharSetOut
  813. );
  814. }
  815. PDNS_RECORD
  816. Dns_RecordListCopyEx(
  817. IN PDNS_RECORD pRR,
  818. IN DWORD ScreenFlag,
  819. IN DNS_CHARSET CharSetIn,
  820. IN DNS_CHARSET CharSetOut
  821. )
  822. /*++
  823. Routine Description:
  824. Screened copy of record set.
  825. Arguments:
  826. pRR - incoming record set
  827. ScreenFlag - flag with record screening parameters
  828. CharSetIn - incoming record's character set
  829. CharSetOut -- char set for resulting record
  830. Return Value:
  831. Ptr to new record set, if successful.
  832. NULL on error.
  833. --*/
  834. {
  835. PDNS_RECORD prr; // most recent copied
  836. PDNS_RECORD prevIn; // previous in set being copied
  837. DNS_RRSET rrset;
  838. DNSDBG( TRACE, (
  839. "Dns_RecordListCopyEx( %p, %08x, %d, %d )\n",
  840. pRR,
  841. ScreenFlag,
  842. CharSetIn,
  843. CharSetOut ));
  844. // init copy rrset
  845. DNS_RRSET_INIT( rrset );
  846. //
  847. // loop through RR set, add records to either match or diff sets
  848. //
  849. prevIn = NULL;
  850. prr = NULL;
  851. while ( pRR )
  852. {
  853. // skip copy on record not matching copy criteria
  854. if ( ScreenFlag )
  855. {
  856. if ( !Dns_ScreenRecord( pRR, ScreenFlag ) )
  857. {
  858. pRR = pRR->pNext;
  859. continue;
  860. }
  861. }
  862. prr = privateRecordCopy(
  863. pRR,
  864. prevIn,
  865. prr, // previous rr copied
  866. CharSetIn,
  867. CharSetOut
  868. );
  869. if ( prr )
  870. {
  871. DNS_RRSET_ADD( rrset, prr );
  872. prevIn = pRR;
  873. pRR = pRR->pNext;
  874. continue;
  875. }
  876. // if fail, toss entire new set
  877. Dns_RecordListFree( rrset.pFirstRR );
  878. return( NULL );
  879. }
  880. return( rrset.pFirstRR );
  881. }
  882. //
  883. // End rrcopy.c
  884. //