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

1218 lines
22 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. local.c
  5. Abstract:
  6. Domain Name System (DNS) Server -- Admin Client API
  7. DNS Admin API calls that do not use RPC.
  8. Completely executed in client library.
  9. Author:
  10. Jim Gilroy (jamesg) 14-Oct-1995
  11. Environment:
  12. User Mode - Win32
  13. Revision History:
  14. --*/
  15. #include "dnsclip.h"
  16. //
  17. // Debug globals
  18. //
  19. DWORD LocalDebugFlag;
  20. //
  21. // Buffer size for building WKS services string
  22. //
  23. #define WKS_SERVICES_BUFFER_SIZE (0x1000) // 4k
  24. VOID
  25. DNS_API_FUNCTION
  26. DnssrvInitializeDebug(
  27. VOID
  28. )
  29. /*++
  30. Routine Description:
  31. Initialize debugging -- use dnslib debugging.
  32. Only purpose is generic interface that hides file flag
  33. and name info so no need to put in header.
  34. --*/
  35. {
  36. #if DBG
  37. Dns_StartDebug(
  38. 0,
  39. DNSRPC_DEBUG_FLAG_FILE,
  40. & LocalDebugFlag,
  41. DNSRPC_DEBUG_FILE_NAME,
  42. 1000000 // 1mb wrap
  43. );
  44. DNS_PRINT(( "LocalDebugFlag = %p\n", LocalDebugFlag ));
  45. #endif
  46. }
  47. PVOID
  48. DnssrvMidlAllocZero(
  49. IN DWORD dwSize
  50. )
  51. /*++
  52. Routine Description:
  53. MIDL allocate and zero memory.
  54. Arguments:
  55. Return Value:
  56. Ptr to allocated and zeroed memory.
  57. --*/
  58. {
  59. PVOID ptr;
  60. ptr = MIDL_user_allocate( dwSize );
  61. if ( !ptr )
  62. {
  63. return( NULL );
  64. }
  65. RtlZeroMemory(
  66. ptr,
  67. dwSize );
  68. return( ptr );
  69. }
  70. VOID
  71. DNS_API_FUNCTION
  72. DnssrvFreeRpcBuffer(
  73. IN OUT PDNS_RPC_BUFFER pBuf
  74. )
  75. /*++
  76. Routine Description:
  77. Free generic (no substructures) RPC buffer.
  78. Arguments:
  79. pBuf -- ptr to buf to free
  80. Return Value:
  81. None
  82. --*/
  83. {
  84. if ( !pBuf )
  85. {
  86. return;
  87. }
  88. MIDL_user_free( pBuf );
  89. }
  90. VOID
  91. DNS_API_FUNCTION
  92. DnssrvFreeServerInfo(
  93. IN OUT PDNS_RPC_SERVER_INFO pServerInfo
  94. )
  95. /*++
  96. Routine Description:
  97. Deep free of DNS_SERVER_INFO structure.
  98. Arguments:
  99. pServerInfo -- ptr to server info to free
  100. Return Value:
  101. None
  102. --*/
  103. {
  104. if ( !pServerInfo )
  105. {
  106. return;
  107. }
  108. //
  109. // free allocated items inside the server info blob
  110. //
  111. if ( pServerInfo->pszServerName )
  112. {
  113. MIDL_user_free( pServerInfo->pszServerName );
  114. }
  115. if ( pServerInfo->aipServerAddrs )
  116. {
  117. MIDL_user_free( pServerInfo->aipServerAddrs );
  118. }
  119. if ( pServerInfo->aipListenAddrs )
  120. {
  121. MIDL_user_free( pServerInfo->aipListenAddrs );
  122. }
  123. if ( pServerInfo->aipForwarders )
  124. {
  125. MIDL_user_free( pServerInfo->aipForwarders );
  126. }
  127. if ( pServerInfo->aipLogFilter )
  128. {
  129. MIDL_user_free( pServerInfo->aipLogFilter );
  130. }
  131. if ( pServerInfo->pwszLogFilePath )
  132. {
  133. MIDL_user_free( pServerInfo->pwszLogFilePath );
  134. }
  135. if ( pServerInfo->pszDsContainer )
  136. {
  137. MIDL_user_free( pServerInfo->pszDsContainer );
  138. }
  139. if ( pServerInfo->pszDomainName )
  140. {
  141. MIDL_user_free( pServerInfo->pszDomainName );
  142. }
  143. if ( pServerInfo->pszForestName )
  144. {
  145. MIDL_user_free( pServerInfo->pszForestName );
  146. }
  147. if ( pServerInfo->pszDomainDirectoryPartition )
  148. {
  149. MIDL_user_free( pServerInfo->pszDomainDirectoryPartition );
  150. }
  151. if ( pServerInfo->pszForestDirectoryPartition )
  152. {
  153. MIDL_user_free( pServerInfo->pszForestDirectoryPartition );
  154. }
  155. //
  156. // free DNS_SERVER_INFO struct itself
  157. //
  158. MIDL_user_free( pServerInfo );
  159. }
  160. VOID
  161. DNS_API_FUNCTION
  162. DnssrvFreeZoneInfo(
  163. IN OUT PDNS_RPC_ZONE_INFO pZoneInfo
  164. )
  165. /*++
  166. Routine Description:
  167. Deep free of DNS_ZONE_INFO structure.
  168. Arguments:
  169. pZoneInfo -- ptr to zone info to free
  170. Return Value:
  171. None
  172. --*/
  173. {
  174. if ( !pZoneInfo )
  175. {
  176. return;
  177. }
  178. //
  179. // free substructures
  180. // - name string
  181. // - data file string
  182. // - secondary IP array
  183. // - WINS server array
  184. //
  185. if ( pZoneInfo->pszZoneName )
  186. {
  187. MIDL_user_free( pZoneInfo->pszZoneName );
  188. }
  189. if ( pZoneInfo->pszDataFile )
  190. {
  191. MIDL_user_free( pZoneInfo->pszDataFile );
  192. }
  193. if ( pZoneInfo->aipMasters )
  194. {
  195. MIDL_user_free( pZoneInfo->aipMasters );
  196. }
  197. if ( pZoneInfo->aipSecondaries )
  198. {
  199. MIDL_user_free( pZoneInfo->aipSecondaries );
  200. }
  201. if ( pZoneInfo->pszDpFqdn )
  202. {
  203. MIDL_user_free( pZoneInfo->pszDpFqdn );
  204. }
  205. if ( pZoneInfo->pwszZoneDn )
  206. {
  207. MIDL_user_free( pZoneInfo->pwszZoneDn );
  208. }
  209. //
  210. // free DNS_ZONE_INFO struct itself
  211. //
  212. MIDL_user_free( pZoneInfo );
  213. }
  214. VOID
  215. DNS_API_FUNCTION
  216. DnssrvFreeNode(
  217. IN OUT PDNS_NODE pNode,
  218. IN BOOLEAN fFreeRecords
  219. )
  220. {
  221. if ( pNode->pRecord )
  222. {
  223. Dns_RecordListFree(
  224. pNode->pRecord,
  225. TRUE );
  226. }
  227. if ( pNode->Flags.S.FreeOwner )
  228. {
  229. FREE_HEAP( pNode->pName );
  230. }
  231. FREE_HEAP( pNode );
  232. }
  233. VOID
  234. DNS_API_FUNCTION
  235. DnssrvFreeNodeList(
  236. IN OUT PDNS_NODE pNode,
  237. IN BOOLEAN fFreeRecords
  238. )
  239. {
  240. PDNS_NODE pnext;
  241. // free all nodes in list
  242. while ( pNode )
  243. {
  244. pnext = pNode->pNext;
  245. DnssrvFreeNode(
  246. pNode,
  247. fFreeRecords );
  248. pNode = pnext;
  249. }
  250. }
  251. VOID
  252. DNS_API_FUNCTION
  253. DnssrvFreeZone(
  254. IN OUT PDNS_RPC_ZONE pZone
  255. )
  256. /*++
  257. Routine Description:
  258. Deep free of DNS_RPC_ZONE structure.
  259. Arguments:
  260. pZone -- ptr to zone to free
  261. Return Value:
  262. None
  263. --*/
  264. {
  265. if ( !pZone )
  266. {
  267. return;
  268. }
  269. // free zone name, then zone itself
  270. if ( pZone->pszZoneName )
  271. {
  272. MIDL_user_free( pZone->pszZoneName );
  273. }
  274. if ( pZone->pszDpFqdn )
  275. {
  276. MIDL_user_free( pZone->pszDpFqdn );
  277. }
  278. MIDL_user_free( pZone );
  279. }
  280. VOID
  281. DNS_API_FUNCTION
  282. DnssrvFreeZoneList(
  283. IN OUT PDNS_RPC_ZONE_LIST pZoneList
  284. )
  285. /*++
  286. Routine Description:
  287. Deep free of list of DNS_RPC_ZONE structures.
  288. Arguments:
  289. pZoneList -- ptr RPC_ZONE_LIST structure to free
  290. Return Value:
  291. None
  292. --*/
  293. {
  294. DWORD i;
  295. PDNS_RPC_ZONE pzone;
  296. if ( !pZoneList )
  297. {
  298. return;
  299. }
  300. for( i=0; i< pZoneList->dwZoneCount; i++ )
  301. {
  302. // zone name is only sub-structure
  303. pzone = pZoneList->ZoneArray[i];
  304. MIDL_user_free( pzone->pszZoneName );
  305. MIDL_user_free( pzone );
  306. }
  307. MIDL_user_free( pZoneList );
  308. }
  309. VOID
  310. DNS_API_FUNCTION
  311. DnssrvFreeDirectoryPartitionEnum(
  312. IN OUT PDNS_RPC_DP_ENUM pDp
  313. )
  314. /*++
  315. Routine Description:
  316. Deep free of PDNS_RPC_DP_ENUM structure.
  317. Arguments:
  318. pDp -- ptr to directory partition to free
  319. Return Value:
  320. None
  321. --*/
  322. {
  323. if ( !pDp )
  324. {
  325. return;
  326. }
  327. if ( pDp->pszDpFqdn )
  328. {
  329. MIDL_user_free( pDp->pszDpFqdn );
  330. }
  331. MIDL_user_free( pDp );
  332. }
  333. VOID
  334. DNS_API_FUNCTION
  335. DnssrvFreeDirectoryPartitionInfo(
  336. IN OUT PDNS_RPC_DP_INFO pDp
  337. )
  338. /*++
  339. Routine Description:
  340. Deep free of PDNS_RPC_DP_INFO structure.
  341. Arguments:
  342. pDp -- ptr to directory partition to free
  343. Return Value:
  344. None
  345. --*/
  346. {
  347. DWORD i;
  348. if ( !pDp )
  349. {
  350. return;
  351. }
  352. if ( pDp->pszDpFqdn )
  353. {
  354. MIDL_user_free( pDp->pszDpFqdn );
  355. }
  356. if ( pDp->pszDpDn )
  357. {
  358. MIDL_user_free( pDp->pszDpDn );
  359. }
  360. if ( pDp->pszCrDn )
  361. {
  362. MIDL_user_free( pDp->pszCrDn );
  363. }
  364. for( i = 0; i < pDp->dwReplicaCount; i++ )
  365. {
  366. PDNS_RPC_DP_REPLICA p = pDp->ReplicaArray[ i ];
  367. if ( p )
  368. {
  369. if ( p->pszReplicaDn )
  370. {
  371. MIDL_user_free( p->pszReplicaDn );
  372. }
  373. MIDL_user_free( p );
  374. }
  375. }
  376. MIDL_user_free( pDp );
  377. }
  378. VOID
  379. DNS_API_FUNCTION
  380. DnssrvFreeDirectoryPartitionList(
  381. IN OUT PDNS_RPC_DP_LIST pDpList
  382. )
  383. /*++
  384. Routine Description:
  385. Deep free of list of PDNS_RPC_DP_LIST structures.
  386. Arguments:
  387. pZoneList -- ptr PDNS_RPC_DP_LIST structure to free
  388. Return Value:
  389. None
  390. --*/
  391. {
  392. DWORD i;
  393. PDNS_RPC_DP_ENUM pDp;
  394. if ( !pDpList )
  395. {
  396. return;
  397. }
  398. for( i=0; i < pDpList->dwDpCount; ++i )
  399. {
  400. pDp = pDpList->DpArray[ i ];
  401. DnssrvFreeDirectoryPartitionEnum( pDp );
  402. }
  403. MIDL_user_free( pDpList );
  404. }
  405. PCHAR
  406. DnssrvGetWksServicesInRecord(
  407. IN PDNS_FLAT_RECORD pRR
  408. )
  409. /*++
  410. Routine Description:
  411. Get list of services in WKS record.
  412. Arguments:
  413. pRR - flat WKS record being written
  414. Return Value:
  415. Ptr to services string, caller MUST free.
  416. NULL on error.
  417. --*/
  418. {
  419. struct servent * pServent;
  420. struct protoent * pProtoent;
  421. INT i;
  422. DWORD length;
  423. USHORT port;
  424. UCHAR bBitmask;
  425. CHAR buffer[ WKS_SERVICES_BUFFER_SIZE ];
  426. PCHAR pch = buffer;
  427. PCHAR pchstart;
  428. PCHAR pchstop;
  429. // protocol
  430. pProtoent = getprotobynumber( (INT) pRR->Data.WKS.chProtocol );
  431. if ( ! pProtoent )
  432. {
  433. DNS_PRINT((
  434. "ERROR: Unable to find protocol %d, writing WKS record.\n",
  435. (INT) pRR->Data.WKS.chProtocol
  436. ));
  437. return( NULL );
  438. }
  439. //
  440. // services
  441. //
  442. // find each bit set in bitmask, lookup and write service
  443. // corresponding to that port
  444. //
  445. // note, that since that port zero is the front of port bitmask,
  446. // lowest ports are the highest bits in each byte
  447. //
  448. pchstart = pch;
  449. pchstop = pch + WKS_SERVICES_BUFFER_SIZE;
  450. for ( i = 0;
  451. i < (INT)(pRR->wDataLength - SIZEOF_WKS_FIXED_DATA);
  452. i++ )
  453. {
  454. bBitmask = (UCHAR) pRR->Data.WKS.bBitMask[i];
  455. port = i * 8;
  456. // write service name for each bit set in byte
  457. // - get out as soon byte is empty of ports
  458. // - terminate each name with blank (until last)
  459. while ( bBitmask )
  460. {
  461. if ( bBitmask & 0x80 )
  462. {
  463. pServent = getservbyport(
  464. (INT) htons(port),
  465. pProtoent->p_name );
  466. if ( pServent )
  467. {
  468. INT copyCount = strlen(pServent->s_name);
  469. pch++;
  470. if ( pchstop - pch <= copyCount+1 )
  471. {
  472. return( NULL );
  473. }
  474. RtlCopyMemory(
  475. pch,
  476. pServent->s_name,
  477. copyCount );
  478. pch += copyCount;
  479. *pch = ' ';
  480. }
  481. else
  482. {
  483. DNS_PRINT((
  484. "ERROR: Unable to find service for port %d, "
  485. "writing WKS record.\n",
  486. port
  487. ));
  488. pch += sprintf( pch, "%d", port );
  489. }
  490. }
  491. port++; // next service port
  492. bBitmask <<= 1; // shift mask up to read next port
  493. }
  494. }
  495. // NULL terminate services string
  496. // and determine length
  497. *pch++ = 0;
  498. length = (DWORD) (pch - pchstart);
  499. // allocate copy of this string
  500. pch = ALLOCATE_HEAP( length );
  501. if ( !pch )
  502. {
  503. SetLastError( DNS_ERROR_NO_MEMORY );
  504. return( NULL );
  505. }
  506. RtlCopyMemory(
  507. pch,
  508. pchstart,
  509. length );
  510. return( pch );
  511. }
  512. //
  513. // Build LDAP \ DS names for objects
  514. //
  515. //
  516. // Build Unicode LDAP paths
  517. //
  518. #define DN_TEXT(string) (L##string)
  519. LPWSTR
  520. DNS_API_FUNCTION
  521. DnssrvCreateDsNodeName(
  522. IN PDNS_RPC_SERVER_INFO pServerInfo,
  523. IN LPWSTR pszZone,
  524. IN LPWSTR pszNode
  525. )
  526. /*++
  527. Routine Description:
  528. Build node DS name.
  529. Arguments:
  530. pServerInfo -- server info for server
  531. pszZone -- zone name
  532. pszNode -- node name RELATIVE to zone root
  533. Return Value:
  534. Ptr to node's DS name. Caller must free.
  535. NULL on error.
  536. --*/
  537. {
  538. PWCHAR psznodeDN;
  539. DWORD length;
  540. // if not DS integrated, bail
  541. if ( !pServerInfo->pszDsContainer )
  542. {
  543. return( NULL );
  544. }
  545. // special case zone root
  546. if ( !pszNode )
  547. {
  548. pszNode = DN_TEXT("@");
  549. }
  550. // allocate required space
  551. length = sizeof(DN_TEXT("dc=,dc=, "));
  552. length += sizeof(WCHAR) * wcslen( pszNode );
  553. length += sizeof(WCHAR) * wcslen( pszZone );
  554. length += sizeof(WCHAR) * wcslen( (LPWSTR)pServerInfo->pszDsContainer );
  555. psznodeDN = (PWCHAR) ALLOCATE_HEAP( length );
  556. if ( !psznodeDN )
  557. {
  558. return( psznodeDN );
  559. }
  560. // build DN
  561. wcscpy( psznodeDN, DN_TEXT("dc=") );
  562. wcscat( psznodeDN, pszNode );
  563. length = wcslen(psznodeDN);
  564. ASSERT ( length > 3 );
  565. if ( length != 4 && // "dc=." case
  566. psznodeDN[ length - 1 ] == '.' )
  567. {
  568. //
  569. // we have a dot terminated node name, strip it out
  570. //
  571. psznodeDN[ length - 1 ] = '\0';
  572. }
  573. wcscat( psznodeDN, DN_TEXT(",dc=") );
  574. wcscat( psznodeDN, pszZone );
  575. length = wcslen(psznodeDN);
  576. ASSERT ( length > 1 );
  577. if ( 1 != wcslen ( pszZone ) && // zone = "." case
  578. psznodeDN[ length - 1 ] == '.' )
  579. {
  580. //
  581. // we have a dot terminated zone name, strip it out
  582. //
  583. psznodeDN[ length - 1 ] = '\0';
  584. }
  585. wcscat( psznodeDN, DN_TEXT(",") );
  586. wcscat( psznodeDN, (LPWSTR)pServerInfo->pszDsContainer );
  587. DNSDBG( STUB, (
  588. "Node DN built: %s\n",
  589. psznodeDN ));
  590. return( psznodeDN );
  591. }
  592. LPWSTR
  593. DNS_API_FUNCTION
  594. DnssrvCreateDsZoneName(
  595. IN PDNS_RPC_SERVER_INFO pServerInfo,
  596. IN LPWSTR pszZone
  597. )
  598. /*++
  599. Routine Description:
  600. Build zone DS name.
  601. This routine should only be used for legacy zones on W2K servers.
  602. For Whistler+ servers the zone info structure has the zone object DN.
  603. Arguments:
  604. pServerInfo -- server info for server
  605. pszZone -- zone name
  606. Return Value:
  607. Ptr to zone's DS name. Caller must free.
  608. NULL on error.
  609. --*/
  610. {
  611. PWCHAR pszzoneDN;
  612. DWORD length;
  613. // if not DS integrated, bail
  614. if ( !(LPWSTR)pServerInfo->pszDsContainer )
  615. {
  616. return( NULL );
  617. }
  618. // allocate required space
  619. length = sizeof(DN_TEXT("dc=, "));
  620. length += sizeof(WCHAR) * wcslen( pszZone );
  621. length += sizeof(WCHAR) * wcslen( (LPWSTR)pServerInfo->pszDsContainer );
  622. pszzoneDN = (PWCHAR) ALLOCATE_HEAP( length );
  623. if ( !pszzoneDN )
  624. {
  625. return( pszzoneDN );
  626. }
  627. // build DN
  628. wcscpy( pszzoneDN, DN_TEXT("dc=") );
  629. wcscat( pszzoneDN, pszZone );
  630. length = wcslen(pszzoneDN);
  631. ASSERT ( length > 1 );
  632. if ( length != 4 && // "dc=." case
  633. pszzoneDN[ length - 1 ] == '.' )
  634. {
  635. //
  636. // we have a dot terminated zone name, strip it out
  637. //
  638. pszzoneDN[ length - 1 ] = '\0';
  639. }
  640. wcscat( pszzoneDN, DN_TEXT(",") );
  641. wcscat( pszzoneDN, (LPWSTR)pServerInfo->pszDsContainer );
  642. DNSDBG( STUB, (
  643. "Zone DN built: %s\n",
  644. pszzoneDN ));
  645. return( pszzoneDN );
  646. }
  647. LPWSTR
  648. DNS_API_FUNCTION
  649. DnssrvCreateDsServerName(
  650. IN PDNS_RPC_SERVER_INFO pServerInfo
  651. )
  652. /*++
  653. Routine Description:
  654. Build zone DS name.
  655. Arguments:
  656. pServerInfo -- server info for server
  657. Return Value:
  658. Ptr to server's DS name. Caller must free.
  659. NULL on error.
  660. --*/
  661. {
  662. PWCHAR pszserverDN;
  663. DWORD length;
  664. //
  665. // DEVNOTE: need investigation here,
  666. // may just be able to use DNS folder in DS
  667. //
  668. // if not DS integrated, bail
  669. if ( !(LPWSTR)pServerInfo->pszDsContainer )
  670. {
  671. return( NULL );
  672. }
  673. // allocate space
  674. length = sizeof(DN_TEXT(" "));
  675. length += sizeof(WCHAR) * wcslen( (LPWSTR)pServerInfo->pszDsContainer );
  676. pszserverDN = (PWCHAR) ALLOCATE_HEAP( length );
  677. if ( !pszserverDN )
  678. {
  679. return( pszserverDN );
  680. }
  681. // build DN
  682. wcscpy( pszserverDN, (LPWSTR)pServerInfo->pszDsContainer );
  683. DNSDBG( STUB, (
  684. "Server DN built: %s\n",
  685. pszserverDN ));
  686. return( pszserverDN );
  687. }
  688. //
  689. // End local.c
  690. //
  691. #if 0
  692. VOID
  693. convertRpcUnionTypeToUnicode(
  694. IN DWORD dwTypeId,
  695. IN OUT DNS_RPC_UNION pData
  696. )
  697. /*++
  698. Routine Description:
  699. Convert RPC union types to unicode.
  700. Arguments:
  701. Return Value:
  702. None
  703. --*/
  704. {
  705. switch ( dwTypeId )
  706. {
  707. case DNSSRV_TYPEID_LPSTR:
  708. pwideString = DnsStringCopyAllocateEx(
  709. pData.String,
  710. 0,
  711. FALSE, // UTF8 in
  712. TRUE // Unicode out
  713. );
  714. if ( !pwideString )
  715. {
  716. ASSERT( FALSE );
  717. return;
  718. }
  719. MIDL_user_free( pData.String );
  720. pData.String = (LPSTR) pwideString;
  721. case DNSSRV_TYPEID_SERVER_INFO:
  722. DnsPrint_RpcServerInfo(
  723. PrintRoutine,
  724. pszHeader,
  725. (PDNS_RPC_SERVER_INFO) pData );
  726. break;
  727. case DNSSRV_TYPEID_ZONE:
  728. DnsPrint_RpcZone(
  729. PrintRoutine,
  730. pszHeader,
  731. (PDNS_RPC_ZONE) pData );
  732. break;
  733. case DNSSRV_TYPEID_ZONE_INFO:
  734. DnsPrint_RpcZoneInfo(
  735. PrintRoutine,
  736. pszHeader,
  737. (PDNS_RPC_ZONE_INFO) pData );
  738. break;
  739. case DNSSRV_TYPEID_ZONE_DBASE_INFO:
  740. PrintRoutine(
  741. "%sZone Dbase Info:\n"
  742. "\tDS Integrated = %d\n"
  743. "\tFile Name = %s\n",
  744. pszHeader,
  745. ((PDNS_RPC_ZONE_DBASE_INFO)pData)->fDsIntegrated,
  746. ((PDNS_RPC_ZONE_DBASE_INFO)pData)->pszFileName );
  747. break;
  748. }
  749. VOID
  750. convertStringToUnicodeInPlace(
  751. IN LPSTR * ppszString
  752. )
  753. /*++
  754. Routine Description:
  755. Convert string to unicode and return it to its current
  756. position in structure.
  757. Arguments:
  758. Return Value:
  759. None
  760. --*/
  761. {
  762. switch ( dwTypeId )
  763. {
  764. case DNSSRV_TYPEID_LPSTR:
  765. pwideString = Dns_StringCopyAllocateEx(
  766. pData.String,
  767. 0,
  768. FALSE, // UTF8 in
  769. TRUE // Unicode out
  770. );
  771. if ( !pwideString )
  772. {
  773. ASSERT( FALSE );
  774. return;
  775. }
  776. MIDL_user_free( pData.String );
  777. pData.String = (LPSTR) pwideString;
  778. case DNSSRV_TYPEID_SERVER_INFO:
  779. DnsPrint_RpcServerInfo(
  780. PrintRoutine,
  781. pszHeader,
  782. (PDNS_RPC_SERVER_INFO) pData );
  783. break;
  784. case DNSSRV_TYPEID_STATS:
  785. DnsPrint_RpcStatistics(
  786. PrintRoutine,
  787. pszHeader,
  788. (PDNS_RPC_STATISTICS) pData );
  789. break;
  790. case DNSSRV_TYPEID_ZONE:
  791. DnsPrint_RpcZone(
  792. PrintRoutine,
  793. pszHeader,
  794. (PDNS_RPC_ZONE) pData );
  795. break;
  796. case DNSSRV_TYPEID_FORWARDERS:
  797. DnsPrint_RpcIpArrayPlusParameters(
  798. PrintRoutine,
  799. pszHeader,
  800. "Forwarders Info:",
  801. "Slave",
  802. ((PDNS_RPC_FORWARDERS)pData)->fSlave,
  803. "Timeout",
  804. ((PDNS_RPC_FORWARDERS)pData)->dwForwardTimeout,
  805. "\tForwarders:\n",
  806. ((PDNS_RPC_FORWARDERS)pData)->aipForwarders );
  807. break;
  808. case DNSSRV_TYPEID_ZONE_INFO:
  809. DnsPrint_RpcZoneInfo(
  810. PrintRoutine,
  811. pszHeader,
  812. (PDNS_RPC_ZONE_INFO) pData );
  813. break;
  814. case DNSSRV_TYPEID_ZONE_SECONDARIES:
  815. DnsPrint_RpcIpArrayPlusParameters(
  816. PrintRoutine,
  817. pszHeader,
  818. "Zone Secondary Info:",
  819. "Secure Secondaries",
  820. ((PDNS_RPC_ZONE_SECONDARIES)pData)->fSecureSecondaries,
  821. NULL,
  822. 0,
  823. "\tSecondaries:\n",
  824. ((PDNS_RPC_ZONE_SECONDARIES)pData)->aipSecondaries );
  825. break;
  826. case DNSSRV_TYPEID_ZONE_TYPE_RESET:
  827. DnsPrint_RpcIpArrayPlusParameters(
  828. PrintRoutine,
  829. pszHeader,
  830. "Zone Type Reset Info:",
  831. "ZoneType",
  832. ((PDNS_RPC_ZONE_TYPE_RESET)pData)->dwZoneType,
  833. NULL,
  834. 0,
  835. "\tMasters:\n",
  836. ((PDNS_RPC_ZONE_TYPE_RESET)pData)->aipMasters );
  837. break;
  838. case DNSSRV_TYPEID_ZONE_DBASE_INFO:
  839. PrintRoutine(
  840. "%sZone Dbase Info:\n"
  841. "\tDS Integrated = %d\n"
  842. "\tFile Name = %s\n",
  843. pszHeader,
  844. ((PDNS_RPC_ZONE_DBASE_INFO)pData)->fDsIntegrated,
  845. ((PDNS_RPC_ZONE_DBASE_INFO)pData)->pszFileName );
  846. break;
  847. default:
  848. PrintRoutine(
  849. "%s\n"
  850. "WARNING: Unknown RPC structure typeid = %d at %p\n",
  851. dwTypeId,
  852. pData );
  853. break;
  854. }
  855. }
  856. #endif
  857. PDNSSRV_STAT
  858. DNS_API_FUNCTION
  859. DnssrvFindStatisticsInBuffer(
  860. IN PDNS_RPC_BUFFER pBuffer,
  861. IN DWORD StatId
  862. )
  863. /*++
  864. Routine Description:
  865. Finds desired statistics in stats buffer.
  866. Arguments:
  867. pStatsBuf -- stats buffer
  868. StatId -- ID of desired stats
  869. Return Value:
  870. Ptr to desired stats in buffer.
  871. --*/
  872. {
  873. PDNSSRV_STAT pstat;
  874. PCHAR pch;
  875. PCHAR pchstop;
  876. pch = pBuffer->Buffer;
  877. pchstop = pch + pBuffer->dwLength;
  878. //
  879. // check all stat blobs within buffer
  880. //
  881. while ( pch < pchstop )
  882. {
  883. pstat = (PDNSSRV_STAT) pch;
  884. pch = (PCHAR) GET_NEXT_STAT_IN_BUFFER( pstat );
  885. if ( pch > pchstop )
  886. {
  887. DNS_PRINT(( "ERROR: invalid stats buffer\n" ));
  888. break;
  889. }
  890. // found matching stats
  891. // - verify correct length
  892. // - return
  893. if ( pstat->Header.StatId == StatId )
  894. {
  895. if ( DnssrvValidityCheckStatistic(pstat) != ERROR_SUCCESS )
  896. {
  897. DNS_PRINT(( "WARNING: Mismatched stats length.\n" ));
  898. break;
  899. }
  900. return( pstat );
  901. }
  902. }
  903. return( NULL );
  904. }