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.

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