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.

1041 lines
22 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. dconvert.c
  5. Abstract:
  6. Domain Name System (DNS) Server -- Admin Client Library
  7. RPC record conversion routines.
  8. Convert DNS_RECORD records into RPC buffer.
  9. Author:
  10. Jing Chen (t-jingc) June, 1998
  11. reverse functions of rconvert.c
  12. Revision History:
  13. --*/
  14. #include "dnsclip.h"
  15. //
  16. // size of string in RPC format
  17. //
  18. #define STRING_UTF8_BUF_SIZE( string, fUnicode ) \
  19. Dns_GetBufferLengthForStringCopy( \
  20. (string), \
  21. 0, \
  22. ((fUnicode) ? DnsCharSetUnicode : DnsCharSetUtf8), \
  23. DnsCharSetUtf8 )
  24. //
  25. // Writing strings to RPC buffer format
  26. //
  27. #define WRITE_STRING_TO_RPC_BUF(buf, psz, len, funicode) \
  28. Dns_StringCopy( \
  29. (buf), \
  30. NULL, \
  31. (psz), \
  32. (len), \
  33. ((funicode) ? DnsCharSetUnicode : DnsCharSetUtf8), \
  34. DnsCharSetUtf8 )
  35. //
  36. // size of name in RPC format
  37. //
  38. #define NAME_UTF8_BUF_SIZE( string, fUnicode ) \
  39. Dns_GetBufferLengthForStringCopy( \
  40. (string), \
  41. 0, \
  42. ((fUnicode) ? DnsCharSetUnicode : DnsCharSetUtf8), \
  43. DnsCharSetUtf8 )
  44. //
  45. // Writing names to RPC buffer format
  46. //
  47. #define WRITE_NAME_TO_RPC_BUF(buf, psz, len, funicode) \
  48. Dns_StringCopy( \
  49. (buf), \
  50. NULL, \
  51. (psz), \
  52. (len), \
  53. ((funicode) ? DnsCharSetUnicode : DnsCharSetUtf8), \
  54. DnsCharSetUtf8 )
  55. //
  56. // Private protos
  57. //
  58. PDNS_RPC_RECORD
  59. Rpc_AllocateRecord(
  60. IN DWORD BufferLength
  61. );
  62. //
  63. // RPC buffer conversion functions
  64. //
  65. PDNS_RPC_RECORD
  66. ADnsRecordConvert(
  67. IN PDNS_RECORD pRR
  68. )
  69. /*++
  70. Routine Description:
  71. Convert A record from DNS Record to RPC buffer.
  72. Arguments:
  73. pRR - record being read
  74. Return Value:
  75. Ptr to new RPC buffer if successful.
  76. NULL on failure.
  77. --*/
  78. {
  79. PDNS_RPC_RECORD prpcRR;
  80. DNS_ASSERT( pRR->wDataLength == sizeof( IP_ADDRESS ) );
  81. prpcRR = Rpc_AllocateRecord( sizeof( IP_ADDRESS ) );
  82. if ( !prpcRR )
  83. {
  84. return NULL;
  85. }
  86. prpcRR->Data.A.ipAddress = pRR->Data.A.IpAddress;
  87. return prpcRR;
  88. }
  89. PDNS_RPC_RECORD
  90. PtrDnsRecordConvert(
  91. IN PDNS_RECORD pRR
  92. )
  93. /*++
  94. Routine Description:
  95. Process PTR compatible record from wire.
  96. Includes: NS, PTR, CNAME, MB, MR, MG, MD, MF
  97. Arguments:
  98. pRR - record being read
  99. Return Value:
  100. Ptr to new RPC buffer if successful.
  101. NULL on failure.
  102. --*/
  103. {
  104. PDNS_RPC_RECORD prpcRR;
  105. DWORD length;
  106. BOOL funicode = IS_UNICODE_RECORD( pRR );
  107. //
  108. // PTR data is another domain name
  109. //
  110. // determine required buffer length and allocate
  111. //
  112. length = NAME_UTF8_BUF_SIZE(pRR->Data.PTR.pNameHost, funicode);
  113. prpcRR = Rpc_AllocateRecord( sizeof( DNS_RPC_NAME ) + length );
  114. if ( !prpcRR )
  115. {
  116. return NULL;
  117. }
  118. //
  119. // write hostname into buffer, immediately following PTR data struct
  120. //
  121. prpcRR->Data.PTR.nameNode.cchNameLength = (UCHAR)length;
  122. WRITE_NAME_TO_RPC_BUF(
  123. prpcRR->Data.PTR.nameNode.achName, // buffer
  124. pRR->Data.PTR.pNameHost,
  125. 0,
  126. funicode );
  127. return prpcRR;
  128. }
  129. PDNS_RPC_RECORD
  130. SoaDnsRecordConvert(
  131. IN PDNS_RECORD pRR
  132. )
  133. /*++
  134. Routine Description:
  135. Convert SOA record from DNS Record to RPC buffer.
  136. Arguments:
  137. pRR - ptr to record being read
  138. Return Value:
  139. Ptr to new RPC buffer if successful.
  140. NULL on failure.
  141. --*/
  142. {
  143. PDNS_RPC_RECORD prpcRR;
  144. DWORD length1;
  145. DWORD length2;
  146. PDNS_RPC_NAME pnamePrimary;
  147. PDNS_RPC_NAME pnameAdmin;
  148. BOOL funicode = IS_UNICODE_RECORD( pRR );
  149. //
  150. // determine required buffer length and allocate
  151. //
  152. length1 = NAME_UTF8_BUF_SIZE( pRR->Data.SOA.pNamePrimaryServer, funicode );
  153. length2 = NAME_UTF8_BUF_SIZE( pRR->Data.SOA.pNameAdministrator, funicode );
  154. prpcRR = Rpc_AllocateRecord(
  155. SIZEOF_SOA_FIXED_DATA +
  156. sizeof( DNS_RPC_NAME ) * 2 +
  157. length1 + length2 );
  158. if ( !prpcRR )
  159. {
  160. return NULL;
  161. }
  162. //
  163. // copy fixed fields
  164. //
  165. RtlCopyMemory(
  166. (PCHAR) & prpcRR->Data.SOA.dwSerialNo,
  167. (PCHAR) & pRR->Data.SOA.dwSerialNo,
  168. SIZEOF_SOA_FIXED_DATA );
  169. //
  170. // copy names into RR buffer
  171. // - primary server immediately follows SOA data struct
  172. // - responsible party follows primary server
  173. //
  174. pnamePrimary = &prpcRR->Data.SOA.namePrimaryServer;
  175. pnamePrimary->cchNameLength = (UCHAR) length1;
  176. pnameAdmin = DNS_GET_NEXT_NAME( pnamePrimary );
  177. pnameAdmin->cchNameLength = (UCHAR) length2;
  178. WRITE_NAME_TO_RPC_BUF(
  179. pnamePrimary->achName,
  180. pRR->Data.Soa.pNamePrimaryServer,
  181. 0,
  182. funicode );
  183. WRITE_NAME_TO_RPC_BUF(
  184. pnameAdmin->achName,
  185. pRR->Data.Soa.pNameAdministrator,
  186. 0,
  187. funicode );
  188. return prpcRR;
  189. }
  190. PDNS_RPC_RECORD
  191. TxtDnsRecordConvert(
  192. IN PDNS_RECORD pRR
  193. )
  194. /*++
  195. Routine Description:
  196. Read TXT compatible record from wire.
  197. Includes: TXT, X25, HINFO, ISDN
  198. Arguments:
  199. pRR - record being read
  200. Return Value:
  201. Ptr to new RPC buffer if successful.
  202. NULL on failure.
  203. --*/
  204. {
  205. PDNS_RPC_RECORD prpcRR;
  206. DWORD bufLength;
  207. DWORD length;
  208. INT count;
  209. PCHAR pch;
  210. PCHAR * ppstring;
  211. BOOL funicode = IS_UNICODE_RECORD( pRR );
  212. //
  213. // determine required buffer length and allocate
  214. // - allocate space for each string
  215. // - and ptr for each string
  216. //
  217. bufLength = 0;
  218. count = pRR->Data.TXT.dwStringCount;
  219. ppstring = pRR->Data.TXT.pStringArray;
  220. while ( count-- )
  221. {
  222. //
  223. // Note: sizeof(DNS_RPC_NAME) is two: 1 char for the length value
  224. // and 1 char for the first char in the name. The max string length
  225. // is 255 because we store the string length in a single byte.
  226. //
  227. length = STRING_UTF8_BUF_SIZE( *ppstring++, funicode );
  228. if ( length > 255 )
  229. {
  230. return NULL;
  231. }
  232. bufLength += sizeof(DNS_RPC_NAME) + length - 1;
  233. }
  234. // allocate
  235. prpcRR = Rpc_AllocateRecord( bufLength );
  236. if ( !prpcRR )
  237. {
  238. return NULL;
  239. }
  240. //
  241. // go back through list copying strings to buffer
  242. // - ptrs to strings are saved to argv like data section
  243. // ppstring walks through this section
  244. // - first string written immediately following data section
  245. // - each subsequent string immediately follows predecessor
  246. // pchbuffer keeps ptr to position to write strings
  247. //
  248. // DEVNOTE: this is a mess
  249. //
  250. pch = (PCHAR) &prpcRR->Data.TXT;
  251. ppstring = pRR->Data.TXT.pStringArray;
  252. count = pRR->Data.TXT.dwStringCount;
  253. while ( count-- )
  254. {
  255. length = STRING_UTF8_BUF_SIZE( *ppstring, funicode );
  256. (UCHAR) *pch++ += (UCHAR) length; //+1 for TXT type only
  257. length = WRITE_STRING_TO_RPC_BUF(
  258. pch,
  259. *ppstring++,
  260. 0,
  261. funicode );
  262. pch += length;
  263. #if DBG
  264. DNS_PRINT((
  265. "Read text string %s\n",
  266. *( ppstring - 1 ) ));
  267. #endif
  268. }
  269. return prpcRR;
  270. }
  271. PDNS_RPC_RECORD
  272. MinfoDnsRecordConvert(
  273. IN PDNS_RECORD pRR
  274. )
  275. /*++
  276. Routine Description:
  277. Read MINFO record from wire.
  278. Arguments:
  279. pRR - record being read
  280. Return Value:
  281. Ptr to new RPC buffer if successful.
  282. NULL on failure.
  283. --*/
  284. {
  285. PDNS_RPC_RECORD prpcRR;
  286. DWORD length1;
  287. DWORD length2;
  288. PDNS_RPC_NAME prpcName1;
  289. PDNS_RPC_NAME prpcName2;
  290. BOOL funicode = IS_UNICODE_RECORD( pRR );
  291. //
  292. // determine required buffer length and allocate
  293. //
  294. length1 = NAME_UTF8_BUF_SIZE( pRR->Data.MINFO.pNameMailbox, funicode );
  295. length2 = NAME_UTF8_BUF_SIZE( pRR->Data.MINFO.pNameErrorsMailbox, funicode );
  296. prpcRR = Rpc_AllocateRecord( sizeof( DNS_RPC_NAME ) * 2 + length1 + length2 );
  297. if ( !prpcRR )
  298. {
  299. return NULL;
  300. }
  301. //
  302. // copy names into RR buffer
  303. // - mailbox immediately follows MINFO data struct
  304. // - errors mailbox immediately follows primary server
  305. //
  306. prpcName1 = &prpcRR->Data.MINFO.nameMailBox;
  307. prpcName1->cchNameLength = (UCHAR) length1;
  308. prpcName2 = DNS_GET_NEXT_NAME( prpcName1);
  309. prpcName2->cchNameLength = (UCHAR) length2;
  310. WRITE_NAME_TO_RPC_BUF(
  311. prpcName1->achName,
  312. pRR->Data.MINFO.pNameMailbox,
  313. 0,
  314. funicode );
  315. WRITE_NAME_TO_RPC_BUF(
  316. prpcName2->achName,
  317. pRR->Data.MINFO.pNameErrorsMailbox,
  318. 0,
  319. funicode );
  320. return prpcRR;
  321. }
  322. PDNS_RPC_RECORD
  323. MxDnsRecordConvert(
  324. IN PDNS_RECORD pRR
  325. )
  326. /*++
  327. Routine Description:
  328. convert MX compatible record.
  329. Includes: MX, RT, AFSDB
  330. Arguments:
  331. pRR - record being read
  332. Return Value:
  333. Ptr to new RPC buffer if successful.
  334. NULL on failure.
  335. --*/
  336. {
  337. PDNS_RPC_RECORD prpcRR;
  338. PDNS_RPC_NAME prpcName;
  339. DWORD length;
  340. BOOL funicode = IS_UNICODE_RECORD( pRR );
  341. //
  342. // determine required buffer length and allocate
  343. //
  344. length = NAME_UTF8_BUF_SIZE( pRR->Data.MX.pNameExchange, funicode );
  345. prpcRR = Rpc_AllocateRecord(
  346. SIZEOF_MX_FIXED_DATA + sizeof( DNS_RPC_NAME ) + length );
  347. if ( !prpcRR )
  348. {
  349. return NULL;
  350. }
  351. //
  352. // copy preference
  353. //
  354. prpcRR->Data.MX.wPreference = pRR->Data.MX.wPreference;
  355. //
  356. // write hostname into buffer, immediately following MX struct
  357. //
  358. prpcName = &prpcRR->Data.MX.nameExchange;
  359. prpcName->cchNameLength = (UCHAR) length;
  360. WRITE_NAME_TO_RPC_BUF(
  361. prpcName->achName,
  362. pRR->Data.MX.pNameExchange,
  363. 0,
  364. funicode );
  365. return prpcRR;
  366. }
  367. PDNS_RPC_RECORD
  368. SigDnsRecordConvert(
  369. IN PDNS_RECORD pRR
  370. )
  371. /*++
  372. Routine Description:
  373. Convert SIG record.
  374. Arguments:
  375. pRR - record being read
  376. Return Value:
  377. Ptr to new RPC buffer if successful.
  378. NULL on failure.
  379. --*/
  380. {
  381. PDNS_RPC_RECORD prpcRR;
  382. PDNS_RPC_NAME prpcName;
  383. DWORD nameLength;
  384. DWORD sigLength;
  385. BOOL funicode = IS_UNICODE_RECORD( pRR );
  386. PBYTE pSig;
  387. nameLength = NAME_UTF8_BUF_SIZE( pRR->Data.SIG.pNameSigner, funicode );
  388. sigLength = pRR->wDataLength -
  389. ( DWORD ) ( pRR->Data.SIG.Signature - ( PBYTE ) &pRR->Data.SIG );
  390. prpcRR = Rpc_AllocateRecord(
  391. SIZEOF_SIG_FIXED_DATA + 1 + nameLength + sigLength );
  392. if ( !prpcRR )
  393. {
  394. return NULL;
  395. }
  396. prpcRR->Data.SIG.wTypeCovered = pRR->Data.SIG.wTypeCovered;
  397. prpcRR->Data.SIG.chAlgorithm = pRR->Data.SIG.chAlgorithm;
  398. prpcRR->Data.SIG.chLabelCount = pRR->Data.SIG.chLabelCount;
  399. prpcRR->Data.SIG.dwOriginalTtl = pRR->Data.SIG.dwOriginalTtl;
  400. prpcRR->Data.SIG.dwSigExpiration = pRR->Data.SIG.dwExpiration;
  401. prpcRR->Data.SIG.dwSigInception = pRR->Data.SIG.dwTimeSigned;
  402. prpcRR->Data.SIG.wKeyTag = pRR->Data.SIG.wKeyTag;
  403. prpcName = &prpcRR->Data.SIG.nameSigner;
  404. prpcName->cchNameLength = ( UCHAR ) nameLength;
  405. WRITE_NAME_TO_RPC_BUF(
  406. prpcName->achName,
  407. pRR->Data.SIG.pNameSigner,
  408. 0,
  409. funicode );
  410. pSig = ( PBYTE ) DNS_GET_NEXT_NAME( prpcName );
  411. RtlCopyMemory( pSig, pRR->Data.SIG.Signature, sigLength );
  412. return prpcRR;
  413. } // SigDnsRecordConvert
  414. PDNS_RPC_RECORD
  415. NxtDnsRecordConvert(
  416. IN PDNS_RECORD pRR
  417. )
  418. /*++
  419. Routine Description:
  420. Convert NXT record.
  421. Arguments:
  422. pRR - record being read
  423. Return Value:
  424. Ptr to new RPC buffer if successful.
  425. NULL on failure.
  426. --*/
  427. {
  428. PDNS_RPC_RECORD prpcRR;
  429. PDNS_RPC_NAME prpcName;
  430. DWORD nameLength;
  431. BOOL funicode = IS_UNICODE_RECORD( pRR );
  432. //
  433. // Allocate the RPC record.
  434. //
  435. nameLength = NAME_UTF8_BUF_SIZE( pRR->Data.NXT.pNameNext, funicode );
  436. prpcRR = Rpc_AllocateRecord(
  437. nameLength + 1 +
  438. ( pRR->Data.NXT.wNumTypes + 1 ) * sizeof( WORD ) );
  439. if ( !prpcRR )
  440. {
  441. return NULL;
  442. }
  443. //
  444. // Copy the type array.
  445. //
  446. prpcRR->Data.Nxt.wNumTypeWords = pRR->Data.NXT.wNumTypes;
  447. RtlCopyMemory(
  448. prpcRR->Data.Nxt.wTypeWords,
  449. pRR->Data.NXT.wTypes,
  450. pRR->Data.NXT.wNumTypes * sizeof( WORD ) );
  451. //
  452. // Write the next name.
  453. //
  454. prpcName = ( PDNS_RPC_NAME ) (
  455. ( PBYTE ) &prpcRR->Data.NXT.wTypeWords +
  456. prpcRR->Data.Nxt.wNumTypeWords * sizeof( WORD ) );
  457. prpcName->cchNameLength = ( UCHAR ) nameLength;
  458. WRITE_NAME_TO_RPC_BUF(
  459. prpcName->achName,
  460. pRR->Data.NXT.pNameNext,
  461. 0,
  462. funicode );
  463. return prpcRR;
  464. } // NxtDnsRecordConvert
  465. PDNS_RPC_RECORD
  466. FlatDnsRecordConvert(
  467. IN PDNS_RECORD pRR
  468. )
  469. /*++
  470. Routine Description:
  471. Convert memory copy compatible record.
  472. Includes AAAA and WINS types.
  473. Arguments:
  474. pRR - record being read
  475. Return Value:
  476. Ptr to new RPC buffer if successful.
  477. NULL on failure.
  478. --*/
  479. {
  480. PDNS_RPC_RECORD prpcRR;
  481. DWORD bufLength;
  482. //
  483. // determine required buffer length and allocate
  484. //
  485. bufLength = pRR->wDataLength;
  486. prpcRR = Rpc_AllocateRecord( bufLength );
  487. if ( !prpcRR )
  488. {
  489. return NULL;
  490. }
  491. //
  492. // copy packet data to record
  493. //
  494. RtlCopyMemory(
  495. & prpcRR->Data,
  496. & pRR->Data,
  497. bufLength );
  498. return prpcRR;
  499. }
  500. PDNS_RPC_RECORD
  501. SrvDnsRecordConvert(
  502. IN PDNS_RECORD pRR
  503. )
  504. /*++
  505. Routine Description:
  506. convert SRV record.
  507. Arguments:
  508. pRR - record being read
  509. Return Value:
  510. Ptr to new RPC buffer if successful.
  511. NULL on failure.
  512. --*/
  513. {
  514. PDNS_RPC_RECORD prpcRR;
  515. PDNS_RPC_NAME prpcName;
  516. DWORD length;
  517. BOOL funicode = IS_UNICODE_RECORD( pRR );
  518. //
  519. // determine required buffer length and allocate
  520. //
  521. length = NAME_UTF8_BUF_SIZE( pRR->Data.SRV.pNameTarget, funicode );
  522. prpcRR = Rpc_AllocateRecord(
  523. SIZEOF_SRV_FIXED_DATA + sizeof(DNS_RPC_NAME) + length );
  524. if ( !prpcRR )
  525. {
  526. return NULL;
  527. }
  528. //
  529. // copy SRV fixed fields
  530. //
  531. prpcRR->Data.SRV.wPriority = pRR->Data.SRV.wPriority;
  532. prpcRR->Data.SRV.wWeight = pRR->Data.SRV.wWeight;
  533. prpcRR->Data.SRV.wPort = pRR->Data.SRV.wPort;
  534. //
  535. // write hostname into buffer, immediately following SRV struct
  536. //
  537. prpcName = &prpcRR->Data.SRV.nameTarget;
  538. prpcName->cchNameLength = (UCHAR) length;
  539. WRITE_NAME_TO_RPC_BUF(
  540. prpcName->achName,
  541. pRR->Data.SRV.pNameTarget,
  542. 0,
  543. funicode );
  544. return prpcRR;
  545. }
  546. PDNS_RPC_RECORD
  547. NbstatDnsRecordConvert(
  548. IN PDNS_RECORD pRR
  549. )
  550. /*++
  551. Routine Description:
  552. Read WINSR record from wire.
  553. Arguments:
  554. pRR - record being read
  555. Return Value:
  556. Ptr to new RPC buffer if successful.
  557. NULL on failure.
  558. --*/
  559. {
  560. PDNS_RPC_RECORD prpcRR;
  561. PDNS_RPC_NAME prpcName;
  562. DWORD length;
  563. BOOL funicode = IS_UNICODE_RECORD( pRR );
  564. //
  565. // determine required buffer length and allocate
  566. //
  567. length = NAME_UTF8_BUF_SIZE( pRR->Data.WINSR.pNameResultDomain, funicode );
  568. prpcRR = Rpc_AllocateRecord(
  569. SIZEOF_NBSTAT_FIXED_DATA + sizeof(DNS_RPC_NAME) + length );
  570. if ( !prpcRR )
  571. {
  572. return NULL;
  573. }
  574. //
  575. // copy WINSR fixed fields
  576. //
  577. prpcRR->Data.WINSR.dwMappingFlag = pRR->Data.WINSR.dwMappingFlag;
  578. prpcRR->Data.WINSR.dwLookupTimeout = pRR->Data.WINSR.dwLookupTimeout;
  579. prpcRR->Data.WINSR.dwCacheTimeout = pRR->Data.WINSR.dwCacheTimeout;
  580. //
  581. // write hostname into buffer, immediately following WINSR struct
  582. //
  583. prpcName = &prpcRR->Data.WINSR.nameResultDomain;
  584. prpcName->cchNameLength = (UCHAR) length;
  585. WRITE_NAME_TO_RPC_BUF(
  586. prpcName->achName,
  587. pRR->Data.WINSR.pNameResultDomain,
  588. 0,
  589. funicode );
  590. return prpcRR;
  591. }
  592. //
  593. // Jump table for DNS_RECORD => RPC buffer conversion.
  594. //
  595. typedef PDNS_RPC_RECORD (* RECORD_TO_RPC_CONVERT_FUNCTION)( PDNS_RECORD );
  596. RECORD_TO_RPC_CONVERT_FUNCTION RecordToRpcConvertTable[] =
  597. {
  598. NULL, // ZERO
  599. ADnsRecordConvert, // A
  600. PtrDnsRecordConvert, // NS
  601. PtrDnsRecordConvert, // MD
  602. PtrDnsRecordConvert, // MF
  603. PtrDnsRecordConvert, // CNAME
  604. SoaDnsRecordConvert, // SOA
  605. PtrDnsRecordConvert, // MB
  606. PtrDnsRecordConvert, // MG
  607. PtrDnsRecordConvert, // MR
  608. NULL, // NULL
  609. FlatDnsRecordConvert, // WKS
  610. PtrDnsRecordConvert, // PTR
  611. TxtDnsRecordConvert, // HINFO
  612. MinfoDnsRecordConvert, // MINFO
  613. MxDnsRecordConvert, // MX
  614. TxtDnsRecordConvert, // TXT
  615. MinfoDnsRecordConvert, // RP
  616. MxDnsRecordConvert, // AFSDB
  617. TxtDnsRecordConvert, // X25
  618. TxtDnsRecordConvert, // ISDN
  619. MxDnsRecordConvert, // RT
  620. NULL, // NSAP
  621. NULL, // NSAPPTR
  622. SigDnsRecordConvert, // SIG
  623. NULL, // KEY
  624. NULL, // PX
  625. NULL, // GPOS
  626. FlatDnsRecordConvert, // AAAA
  627. NULL, // 29
  628. NxtDnsRecordConvert, // 30
  629. NULL, // 31
  630. NULL, // 32
  631. SrvDnsRecordConvert, // SRV
  632. NULL, // ATMA
  633. NULL, // 35
  634. NULL, // 36
  635. NULL, // 37
  636. NULL, // 38
  637. NULL, // 39
  638. NULL, // 40
  639. NULL, // OPT
  640. NULL, // 42
  641. NULL, // 43
  642. NULL, // 44
  643. NULL, // 45
  644. NULL, // 46
  645. NULL, // 47
  646. NULL, // 48
  647. //
  648. // NOTE: last type indexed by type ID MUST be set
  649. // as MAX_SELF_INDEXED_TYPE #define in record.h
  650. // (see note above in record info table)
  651. // note these follow, but require OFFSET_TO_WINS_RR subtraction
  652. // from actual type value
  653. NULL, // TKEY
  654. NULL, // TSIG
  655. FlatDnsRecordConvert, // WINS
  656. NbstatDnsRecordConvert // WINS-R
  657. };
  658. PDNS_RPC_RECORD
  659. Rpc_AllocateRecord(
  660. IN DWORD BufferLength
  661. )
  662. /*++
  663. Routine Description:
  664. Allocate RPC record structure.
  665. Arguments:
  666. wBufferLength - desired buffer length (beyond structure header)
  667. Return Value:
  668. Ptr to buffer.
  669. NULL on error.
  670. --*/
  671. {
  672. PDNS_RPC_RECORD prr;
  673. if ( BufferLength > MAXWORD )
  674. {
  675. return NULL;
  676. }
  677. prr = ALLOCATE_HEAP( SIZEOF_DNS_RPC_RECORD_HEADER + BufferLength );
  678. if ( !prr )
  679. {
  680. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  681. return NULL;
  682. }
  683. // set datalength to buffer length
  684. prr->wDataLength = (WORD) BufferLength;
  685. return prr;
  686. }
  687. PDNS_RPC_RECORD
  688. DnsConvertRecordToRpcBuffer(
  689. IN PDNS_RECORD pRecord
  690. )
  691. /*++
  692. Routine Description:
  693. Convert standard DNS record to RPC buffer.
  694. Arguments:
  695. pRecord -- DNS Record to be converted.
  696. //fUnicode -- flag, write records into unicode
  697. Return Value:
  698. Ptr to new RPC buffer if successful.
  699. NULL on failure.
  700. --*/
  701. {
  702. PDNS_RPC_RECORD prpcRecord;
  703. WORD index;
  704. WORD type;
  705. RECORD_TO_RPC_CONVERT_FUNCTION pFunc;
  706. DNS_ASSERT( DNS_IS_DWORD_ALIGNED( pRecord ) );
  707. IF_DNSDBG( RPC2 )
  708. {
  709. DNS_PRINT((
  710. "Enter DnsConvertRecordToRpcBuffer()\n"
  711. " pRecord = %p\n",
  712. pRecord ));
  713. }
  714. //
  715. // convert record
  716. // set unicode flag if converting
  717. //
  718. type = pRecord->wType;
  719. index = INDEX_FOR_TYPE( type );
  720. DNS_ASSERT( index <= MAX_RECORD_TYPE_INDEX );
  721. if ( !index || !(pFunc = RecordToRpcConvertTable[ index ]) )
  722. {
  723. // if unknown type try flat record copy -- best we can
  724. // do to protect if server added new types since admin built
  725. DNS_PRINT((
  726. "ERROR: no DNS_RECORD to RPC conversion routine for type %d\n"
  727. " using flat conversion routine\n",
  728. type ));
  729. pFunc = FlatDnsRecordConvert;
  730. }
  731. prpcRecord = (*pFunc)( pRecord );
  732. if ( ! prpcRecord )
  733. {
  734. DNS_PRINT((
  735. "ERROR: Record build routine failure for record type %d\n"
  736. " status = %p\n\n",
  737. type,
  738. GetLastError() ));
  739. return NULL;
  740. }
  741. //
  742. // fill out record structure
  743. //
  744. prpcRecord->wType = type;
  745. prpcRecord->dwTtlSeconds = pRecord->dwTtl;
  746. IF_DNSDBG( INIT )
  747. {
  748. DNS_PRINT((
  749. "New RPC buffer built\n"
  750. ));
  751. }
  752. IF_DNSDBG( RPC2 )
  753. {
  754. DNS_PRINT(( "Finished DnsConvertRpcBufferToRecords() " ));
  755. }
  756. return prpcRecord;
  757. }
  758. //
  759. // End dconvert.c
  760. //