///////////////////////////////////////////////////////////////////// // // CopyRight ( c ) 1999 Microsoft Corporation // // Module Name: DnsWrap.cpp // // Description: // Implementation of dnswrap class // // Author: // Henry Wang ( henrywa ) March 8, 2000 // // ////////////////////////////////////////////////////////////////////// #include "DnsWmi.h" // // These string tables are in client\print.c // extern "C" LPSTR MemTagStringsNT5[]; extern "C" LPSTR MemTagStrings[]; // // These macros allow us to widen DNS RPC string constants. // #define MYTEXT2(str) L##str #define MYTEXT(str) MYTEXT2(str) // // Globals for statistics. // struct { DWORD dwStatId; const WCHAR * pszName; } g_StatInfo[] = { { DNSSRV_STATID_TIME, L"Time Stats" }, { DNSSRV_STATID_QUERY, L"Query and Response Stats" }, { DNSSRV_STATID_QUERY2, L"Query Stats" }, { DNSSRV_STATID_RECURSE, L"Recursion Stats" }, { DNSSRV_STATID_MASTER, L"Master Stats" }, { DNSSRV_STATID_SECONDARY, L"Secondary Stats" }, { DNSSRV_STATID_WINS, L"WINS Referral Stats" }, { DNSSRV_STATID_WIRE_UPDATE, L"Packet Dynamic Update Stats" }, { DNSSRV_STATID_SKWANSEC, L"SkwanSec Stats" }, { DNSSRV_STATID_DS, L"DS Integration Stats" }, { DNSSRV_STATID_NONWIRE_UPDATE, L"Internal Dynamic Update Stats" }, { DNSSRV_STATID_MEMORY, L"Memory Stats" }, { DNSSRV_STATID_DBASE, L"Database Stats" }, { DNSSRV_STATID_RECORD, L"Record Stats" }, { DNSSRV_STATID_PACKET, L"Packet Memory Usage Stats" }, { DNSSRV_STATID_NBSTAT, L"Nbstat Memory Usage Stats" }, { DNSSRV_STATID_ERRORS, L"Error Stats" }, { DNSSRV_STATID_TIMEOUT, L"Timeout Stats" }, { DNSSRV_STATID_CACHE, L"Query" }, { DNSSRV_STATID_PRIVATE, L"Private Stats" }, { 0, NULL } // terminator }; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CDnsWrap::CDnsWrap() :m_wszpServerName(NULL) { CServerInfo serverInfo; PDNS_RPC_SERVER_INFO pdata = (PDNS_RPC_SERVER_INFO) serverInfo.m_pInfo; char* p = pdata->pszServerName; CharToWchar(p, &m_wszpServerName); } CDnsWrap::~CDnsWrap() { delete [] m_wszpServerName; } CDnsWrap::CServerInfo::CServerInfo() :m_pInfo(NULL) { DWORD dwtypeid; int status = DnssrvQuery( PVD_DNS_LOCAL_SERVER, NULL, DNSSRV_QUERY_SERVER_INFO, &dwtypeid, &m_pInfo); if(status != ERROR_SUCCESS) ThrowException(status); } CDnsWrap::CServerInfo::~CServerInfo() { DnssrvFreeServerInfo((PDNS_RPC_SERVER_INFO)m_pInfo); } CDnsWrap& CDnsWrap::DnsObject(void) { static CDnsWrap dns; return dns; } ///////////////////////////////////////////////////////////////////////////// //++ // // Description: // enumerates record for a give domain. If bRecursive is true, enum all // records including subdomain, otherwise, enum records directly under // the domain. It also take a call back function pFilter to allow // further filtering the records // // Arguments: // objNode [IN ] list of domains // pFilter [IN] pointer a class contains the criteria // on how to filter records // pfFilter [IN] call back function allows further // processing of records using pFilter // bRecursive [IN] true for deep enum, otherwise false // wType, [IN] type of records to enum // dwFlag, [IN] flag // pClass, [IN] wmi class for the type of records to enum // InstMgr [IN] manage wmi object and send them wmi // Return Value: // WBEM_S_NO_ERROR // //-- ///////////////////////////////////////////////////////////////////////////// SCODE CDnsWrap::dnsEnumRecordsForDomainEx( CDomainNode& objNode, PVOID pFilter, FILTER pfFilter, BOOL bRecursive, WORD wType, DWORD dwFlag, IWbemClassObject * pClass, CWbemInstanceMgr& InstMgr ) { CDnsRpcRecordSet RecordSet( objNode, wType, dwFlag, NULL, NULL); PDNS_RPC_NODE pNode=NULL; WCHAR DomainName[MAX_PATH] = L""; while (( pNode = RecordSet.GetNextNode()) != NULL) { CDnsRpcNode dnsNode; CObjPath opNew; if( !dnsNode.Init(pNode)) { return WBEM_E_FAILED; } //find record node if(dnsNode.IsDomainNode()) { // get domain name wstring wstrSubDomainName = dnsNode.GetNodeName();; wstrSubDomainName += PVD_DNS_LOCAL_SERVER + objNode.wstrNodeName; CDomainNode subDomain = objNode; subDomain.wstrNodeName = wstrSubDomainName; //recursion if(bRecursive) { dnsEnumRecordsForDomainEx( subDomain, pFilter, pfFilter, bRecursive, wType, dwFlag, pClass, InstMgr); } } pfFilter( objNode, pFilter, &dnsNode, pClass, InstMgr); } return WBEM_S_NO_ERROR; } SCODE CDnsWrap::dnsGetDomain( CObjPath& objParent, IWbemClassObject* pClass, IWbemObjectSink* pHandler ) { // get top level domain wstring wstrZoneName = objParent.GetStringValueForProperty( PVD_DOMAIN_CONTAINER_NAME); wstring wstrNodeName = objParent.GetStringValueForProperty( PVD_DOMAIN_FQDN); list nodeList; dnsEnumDomainForServer(&nodeList); list::iterator i; BOOL FoundFlag = FALSE; // check for zone for(i=nodeList.begin(); i != nodeList.end(); ++i) { if(_wcsicmp( wstrZoneName.data(), i->wstrZoneName.data()) == 0 ) { // only roothints and catch, NodeName is initialize to // nil, we can't do the compare if(i->wstrNodeName.empty() || (_wcsicmp( wstrNodeName.data(), i->wstrNodeName.data())==0)) { FoundFlag = TRUE; break; } } } // check for domain in container if(! FoundFlag) { DNS_STATUS status ; char *pszZoneName=NULL, *pszNodeName=NULL, *pszStartChild=NULL; DWORD dwBufferLength; PBYTE pBuffer = NULL; WcharToChar(wstrZoneName.data(), &pszZoneName); WcharToChar(wstrNodeName.data(), &pszNodeName); status = DnssrvEnumRecords( PVD_DNS_LOCAL_SERVER, pszZoneName, pszNodeName, pszStartChild, DNS_TYPE_ALL, DNS_RPC_VIEW_ALL_DATA, NULL, NULL, & dwBufferLength, & pBuffer); delete [] pszNodeName; delete [] pszZoneName; DnssrvFreeRecordsBuffer(pBuffer); if (status != ERROR_SUCCESS) ThrowException(status); FoundFlag = TRUE; } if(FoundFlag) { CWbemClassObject Inst; pClass->SpawnInstance(0, &Inst); Inst.SetProperty( wstrNodeName, PVD_DOMAIN_FQDN); Inst.SetProperty( wstrZoneName, PVD_DOMAIN_CONTAINER_NAME); Inst.SetProperty( m_wszpServerName, PVD_DOMAIN_SERVER_NAME); // clean up pHandler->Indicate(1, &Inst); } return WBEM_S_NO_ERROR; } SCODE CDnsWrap::dnsDeleteDomain( char * pszContainer, char * pszDomain ) { LONG status = DnssrvDeleteNode( PVD_DNS_LOCAL_SERVER, pszContainer, pszDomain, 1 //fDeleteSubtree ); if ( status != ERROR_SUCCESS ) { ThrowException(status); } return WBEM_S_NO_ERROR; } ///////////////////////////////////////////////////////////////////////////// //++ // // Description: // enumeratr all zones including cache for local dns server, returns // them as a list of object path // // Arguments: // pList [IN OUT] list of object path to domains // // Return Value: // WBEM_S_NO_ERROR // //-- ///////////////////////////////////////////////////////////////////////////// SCODE CDnsWrap::dnsEnumDomainForServer( list* pList ) { PDNS_RPC_ZONE_LIST pZoneList = NULL; DNS_STATUS status = DnssrvEnumZones( PVD_DNS_LOCAL_SERVER, ZONE_REQUEST_ALL_ZONES_AND_CACHE, NULL, &pZoneList); if(status == ERROR_SUCCESS) { DNS_RPC_ZONE* pDnsZone = NULL; CDnsWrap& dns = CDnsWrap::DnsObject(); for(DWORD i = 0; i < pZoneList->dwZoneCount; i++) { pDnsZone = (pZoneList->ZoneArray[i]); if(_wcsicmp(pDnsZone->pszZoneName, PVD_DNS_LOCAL_SERVER)) { CObjPath opInst; opInst.SetClass(PVD_CLASS_DOMAIN); opInst.AddProperty( PVD_DOMAIN_SERVER_NAME , dns.GetServerName().data() ); opInst.AddProperty( PVD_DOMAIN_CONTAINER_NAME, pDnsZone->pszZoneName ); opInst.AddProperty( PVD_DOMAIN_FQDN, pDnsZone->pszZoneName ); pList->insert( pList->end(), opInst); } } // add catch domain CObjPath opCache; opCache.SetClass(PVD_CLASS_DOMAIN); opCache.AddProperty( PVD_DOMAIN_SERVER_NAME, dns.GetServerName().data() ); opCache.AddProperty( PVD_DOMAIN_CONTAINER_NAME, PVD_DNS_CACHE ); opCache.AddProperty( PVD_DOMAIN_FQDN, PVD_DNS_CACHE ); //add roothints CObjPath opRh; opRh.SetClass(PVD_CLASS_DOMAIN); opRh.AddProperty( PVD_DOMAIN_SERVER_NAME, dns.GetServerName().data() ); opRh.AddProperty( PVD_DOMAIN_CONTAINER_NAME, PVD_DNS_ROOTHINTS ); opRh.AddProperty( PVD_DOMAIN_FQDN, PVD_DNS_ROOTHINTS ); pList->insert(pList->begin(), opRh); pList->insert(pList->begin(), opCache); } // CLEAN UP DnssrvFreeZoneList(pZoneList); if(status != ERROR_SUCCESS) { ThrowException(status); } return WBEM_S_NO_ERROR; } ///////////////////////////////////////////////////////////////////////////// //++ // // Description: // enumeratr all zones including cache for local dns server, returns // them as a list of domain node // // Arguments: // pList [IN OUT] list of domains // // Return Value: // WBEM_S_NO_ERROR // //-- ///////////////////////////////////////////////////////////////////////////// SCODE CDnsWrap::dnsEnumDomainForServer( list* pList ) { PDNS_RPC_ZONE_LIST pZoneList = NULL; LONG status = DnssrvEnumZones( PVD_DNS_LOCAL_SERVER, ZONE_REQUEST_ALL_ZONES_AND_CACHE, NULL, &pZoneList); DNS_RPC_ZONE * pDnsZone = NULL; if( status == ERROR_SUCCESS && pZoneList ) { for(DWORD i = 0; i < pZoneList->dwZoneCount; i++) { pDnsZone = (pZoneList->ZoneArray[i]); if(_wcsicmp(pDnsZone->pszZoneName, L".")) { CDomainNode objNode; objNode.wstrNodeName = pDnsZone->pszZoneName; objNode.wstrZoneName = pDnsZone->pszZoneName; pList->insert(pList->end(), objNode); } } // add catch domain CDomainNode nodeCache; nodeCache.wstrZoneName = PVD_DNS_CACHE; //add roothints CDomainNode nodeRH; nodeRH.wstrZoneName = PVD_DNS_ROOTHINTS; pList->insert(pList->begin(), nodeCache); pList->insert(pList->begin(), nodeRH); } // CLEAN UP DnssrvFreeZoneList(pZoneList); if (status != ERROR_SUCCESS) { ThrowException(status); } return WBEM_S_NO_ERROR; } SCODE CDnsWrap::ValidateServerName( const WCHAR* pwzStr) { if(_wcsicmp(pwzStr, PVD_DNS_LOCAL_SERVER)) if(_wcsicmp(pwzStr, L"127.0.0.1")) if(_wcsicmp(pwzStr, m_wszpServerName) ) return WBEM_E_INVALID_PARAMETER; return WBEM_S_NO_ERROR; } SCODE CDnsWrap::dnsQueryServerInfo( const WCHAR* strServerName, CWbemClassObject& NewInst, IWbemObjectSink* pHandler ) { // get dnsserver DWORD dwtypeid; PVOID pdata=NULL; DNS_STATUS status; PDNS_RPC_SERVER_INFO pServerInfo = NULL; // dww - 6/14/99 // Changed to make see if ValidateServerName does not return WBEM_S_NO_ERROR. // if(WBEM_S_NO_ERROR != ValidateServerName(strServerName)) return WBEM_E_INVALID_PARAMETER; status = DnssrvQuery( strServerName, NULL, DNSSRV_QUERY_SERVER_INFO, &dwtypeid, &pdata); if( status == ERROR_SUCCESS) { pServerInfo = (PDNS_RPC_SERVER_INFO) pdata; NewInst.SetProperty( pServerInfo->dwVersion, PVD_SRV_VERSION); NewInst.SetProperty( pServerInfo->fDsAvailable, PVD_SRV_DS_AVAILABLE); // ListenAddress array if(pServerInfo->aipListenAddrs) { NewInst.SetProperty( pServerInfo->aipListenAddrs->AddrArray, pServerInfo->aipListenAddrs->AddrCount, MYTEXT( DNS_REGKEY_LISTEN_ADDRESSES ) ); } if(pServerInfo->aipForwarders) { NewInst.SetProperty( pServerInfo->aipForwarders->AddrArray, pServerInfo->aipForwarders->AddrCount, MYTEXT( DNS_REGKEY_FORWARDERS ) ); } if(pServerInfo->aipServerAddrs) { NewInst.SetProperty( pServerInfo->aipServerAddrs->AddrArray, pServerInfo->aipServerAddrs->AddrCount, PVD_SRV_SERVER_IP_ADDRESSES_ARRAY); } } DnssrvFreeServerInfo(pServerInfo); if ( status != ERROR_SUCCESS ) { ThrowException(status); } return ERROR_SUCCESS; } SCODE CDnsWrap::dnsRestartServer( WCHAR* strServerName ) { LONG status = DnssrvOperation( strServerName, NULL, DNSSRV_OP_RESTART, DNSSRV_TYPEID_NULL, NULL ); if(status != ERROR_SUCCESS) { ThrowException(status); } return WBEM_S_NO_ERROR; } ///////////////////////////////////////////////////////////////////////////// //++ // // Description: // using property value from wmi instance to set dns server property // // Arguments: // Inst [IN] wmi instance whose property value // to be sent to dns server // // Return Value: // WBEM_S_NO_ERROR // //-- ///////////////////////////////////////////////////////////////////////////// SCODE CDnsWrap::dnsServerPropertySet( CWbemClassObject& Inst, BOOL bGet ) { DBG_FN( "CDnsWrap::dnsServerPropertySet" ) // // get mapping table // DWORD cNumOfEntries; PropertyTable* pt = (PropertyTable*)GetPropertyTable(&cNumOfEntries); for(int i=0; iAddrCount; psa = SafeArrayCreate( VT_BSTR, 1, rgsabound ); if ( psa == NULL ) { sc = WBEM_E_OUT_OF_MEMORY; goto Done; } for ( int i = 0; i < pipArray->AddrCount; ++i ) { BSTR bstr = AllocBstr( IpAddressToString( pipArray->AddrArray[ i ] ).c_str() ); if ( bstr == NULL ) { sc = WBEM_E_OUT_OF_MEMORY; goto Done; } LONG ix = i; sc = SafeArrayPutElement( psa, &ix, bstr ); SysFreeString( bstr ); if ( sc != S_OK ) { goto Done; } } Inst.SetProperty( psa, ( PWCHAR ) wszWbemProperty ); Done: if ( pdata ) { // JJW: do something to free RPC piparray??? } if ( psa ) { SafeArrayDestroy( psa ); } return sc; } // CDnsWrap::dnsGetIPArrayProperty /*--------------------------------------------------------------------------- Read the property value out of the class object and send to DNS server. If the specified property does not exist on the object, do nothing and return WBEM_S_NO_ERROR. */ SCODE CDnsWrap::dnsSetIPArrayProperty( const char * pszZoneName, const WCHAR * wszWbemProperty, const char * pszDnssrvPropertyName, CWbemClassObject & Inst ) { DBG_FN( "CDnsWrap::dnsSetIPArrayProperty" ) SCODE sc = WBEM_S_NO_ERROR; SAFEARRAY * psa = NULL; VARIANT var; VariantInit( &var ); if( Inst.GetProperty( &var, ( LPCWSTR ) wszWbemProperty ) == S_OK && var.vt != VT_NULL ) { DNS_DEBUG( INSTPROV, ( "%s: %s on zone %s\n", fn, pszDnssrvPropertyName, pszZoneName )); if ( var.vt != ( VT_ARRAY |VT_BSTR ) ) { sc = WBEM_E_TYPE_MISMATCH; goto Done; } sc = SafeArrayCopy( var.parray, &psa ); BSTR * pbstr = NULL; sc = SafeArrayAccessData( psa, ( void ** ) &pbstr ); if ( sc != S_OK ) { goto Done; } int ipCount = psa->rgsabound[ 0 ].cElements; IP_ADDRESS * pipAddrArray = new IP_ADDRESS[ ipCount + 1 ]; if ( pipAddrArray == NULL ) { ThrowException( WBEM_E_OUT_OF_MEMORY ); } for ( int i = 0; i < ipCount; ++i ) { string str; WcharToString( pbstr[ i ], str ); pipAddrArray[ i ] = inet_addr( str.c_str() ); } SafeArrayUnaccessData( psa ); PIP_ARRAY pipArray = Dns_BuildIpArray( ipCount, pipAddrArray ); delete [] pipAddrArray; DNS_STATUS status = DnssrvResetIPListProperty( PVD_DNS_LOCAL_SERVER, pszZoneName, pszDnssrvPropertyName, pipArray, 0 ); FREE_HEAP( pipArray ); if( status != ERROR_SUCCESS ) { sc = status; } } Done: VariantClear( &var ); if ( psa ) { SafeArrayDestroy( psa ); } return sc; } // CDnsWrap::dnsSetIPArrayProperty SCODE CDnsWrap::dnsSetServerForwarders( const char * pszZoneName, const WCHAR* wszWbemProperty, const char* pszOperationName, CWbemClassObject & Inst ) { // get forward ip array DWORD* pdwValue=NULL; DWORD dwSize; if(Inst.GetProperty( &pdwValue, &dwSize, (WCHAR*)wszWbemProperty) == S_OK) { DWORD dwSlave; DWORD dwTimeOut; try { // start changing forwarders process // get slave if(Inst.GetProperty( &dwSlave, MYTEXT( DNS_REGKEY_SLAVE ) ) != S_OK) { return WBEM_E_INVALID_PARAMETER; } // get forward time out if(Inst.GetProperty( &dwTimeOut, MYTEXT( DNS_REGKEY_FORWARD_TIMEOUT ) ) != S_OK) { return WBEM_E_INVALID_PARAMETER; } } catch(...) { delete [] pdwValue; throw; } // now let's change it DNS_STATUS status = DnssrvResetForwarders( PVD_DNS_LOCAL_SERVER, dwSize, pdwValue, dwTimeOut, dwSlave ); delete [] pdwValue; if(status != ERROR_SUCCESS) { ThrowException(status); } } return WBEM_S_NO_ERROR; } SCODE CDnsWrap::dnsSetServerListenAddress( const char * pszZoneName, const WCHAR* wszWbemProperty, const char* pszOperationName, CWbemClassObject& Inst ) { // dww - 6/28/99 // Rewrote to accept NULL as a valid parameter. // DWORD* dwValue = NULL; DWORD dwSize = 0; Inst.GetProperty( &dwValue, &dwSize, (WCHAR*)wszWbemProperty); if ( dwSize == 0 ) { dwValue = new DWORD[1]; if ( !dwValue ) { return WBEM_E_OUT_OF_MEMORY; } dwValue[0] = 0; } DNS_STATUS status = DnssrvResetServerListenAddresses( PVD_DNS_LOCAL_SERVER, dwSize, dwValue); delete [] dwValue; if(status != ERROR_SUCCESS) { ThrowException(status); } return WBEM_S_NO_ERROR; } SCODE CDnsWrap::dnsDeleteZone( CObjPath& objZone) { wstring wstrZoneName = objZone.GetStringValueForProperty( PVD_DOMAIN_CONTAINER_NAME ); // dww - 6/14/99 // Added code to see if this is an integrated zone. If it is, you have to use // The DNSSRV_OP_ZONE_DELETE_FROM_DS operation. All other zone types use the // DNSSRV_OP_ZONE_DELETE operation. // // Get the Zone Type to determine if it is an integrated zone. DWORD dwValue = -1; LONG status = WBEM_S_NO_ERROR; char* pszZoneName = NULL; WcharToChar(wstrZoneName.data(), &pszZoneName); DnssrvQueryDwordProperty( PVD_DNS_LOCAL_SERVER, pszZoneName, DNS_REGKEY_ZONE_DS_INTEGRATED, &dwValue ); if(dwValue == 1) // integrated zone { status= DnssrvOperation( PVD_DNS_LOCAL_SERVER, pszZoneName, DNSSRV_OP_ZONE_DELETE_FROM_DS, DNSSRV_TYPEID_NULL, (PVOID) NULL ); } else { status= DnssrvOperation( PVD_DNS_LOCAL_SERVER, pszZoneName, DNSSRV_OP_ZONE_DELETE, DNSSRV_TYPEID_NULL, (PVOID) NULL ); } delete [] pszZoneName; if( status != ERROR_SUCCESS) ThrowException(status); return WBEM_S_NO_ERROR; } wstring CDnsWrap::GetServerName(void) { return m_wszpServerName; } SCODE CDnsWrap::dnsGetZone( const WCHAR* wszServer, const WCHAR* wszZone, CWbemClassObject& Inst, IWbemObjectSink* pHandler ) { DBG_FN( "CDnsWrap::dnsGetZone" ) DNS_STATUS status; char* pszZoneName = NULL; PDNS_RPC_ZONE_INFO pZoneInfo=NULL; WcharToChar(wszZone, &pszZoneName); status = DnssrvGetZoneInfo( wszServer, pszZoneName, &pZoneInfo ); DNS_DEBUG( INSTPROV, ( "%s: server %S zone %S\n", fn, wszServer, wszZone )); DWORD dwDsIntegratedValue = 0; if ( status == ERROR_SUCCESS) { status = DnssrvQueryDwordProperty( PVD_DNS_LOCAL_SERVER, pszZoneName, DNS_REGKEY_ZONE_DS_INTEGRATED, &dwDsIntegratedValue ); } delete [] pszZoneName; if ( status == DNS_ERROR_ZONE_DOES_NOT_EXIST) { return WBEM_E_NOT_FOUND; } // setup wbem object if(status == ERROR_SUCCESS) { Inst.SetProperty( pZoneInfo->dwZoneType, PVD_ZONE_ZONE_TYPE); // setup keys Inst.SetProperty( m_wszpServerName, PVD_DOMAIN_SERVER_NAME); Inst.SetProperty( wszZone, PVD_DOMAIN_CONTAINER_NAME); Inst.SetProperty( wszZone, PVD_DOMAIN_FQDN); Inst.SetProperty( pZoneInfo->fAllowUpdate, PVD_ZONE_ALLOW_UPDATE); Inst.SetProperty( pZoneInfo->fAutoCreated, PVD_ZONE_AUTO_CREATED); Inst.SetProperty( pZoneInfo->fPaused, PVD_ZONE_PAUSED ); Inst.SetProperty( pZoneInfo->fReverse, PVD_ZONE_REVERSE ); Inst.SetProperty( pZoneInfo->fAging, PVD_ZONE_AGING ); Inst.SetProperty( pZoneInfo->fSecureSecondaries, PVD_ZONE_SECURE_SECONDARIES ); Inst.SetProperty( pZoneInfo->fNotifyLevel, PVD_ZONE_NOTIFY); Inst.SetProperty( pZoneInfo->fShutdown, PVD_ZONE_SHUTDOWN ); Inst.SetProperty( pZoneInfo->fUseWins, PVD_ZONE_USE_WINS); Inst.SetProperty( pZoneInfo->pszDataFile, PVD_ZONE_DATA_FILE); Inst.SetProperty( dwDsIntegratedValue, PVD_ZONE_DS_INTEGRATED); Inst.SetProperty( pZoneInfo->dwAvailForScavengeTime, PVD_ZONE_AVAIL_FOR_SCAVENGE_TIME ); Inst.SetProperty( pZoneInfo->dwNoRefreshInterval, PVD_ZONE_NOREFRESH_INTERVAL ); Inst.SetProperty( pZoneInfo->dwRefreshInterval, PVD_ZONE_REFRESH_INTERVAL ); Inst.SetProperty( pZoneInfo->fForwarderSlave, PVD_ZONE_FORWARDER_SLAVE ); Inst.SetProperty( pZoneInfo->dwForwarderTimeout, PVD_ZONE_FORWARDER_TIMEOUT ); if (pZoneInfo->aipMasters != NULL) { Inst.SetProperty( pZoneInfo->aipMasters->AddrArray, pZoneInfo->aipMasters->AddrCount, PVD_ZONE_MASTERS_IP_ADDRESSES_ARRAY ); } if (pZoneInfo->aipSecondaries != NULL) { Inst.SetProperty( pZoneInfo->aipSecondaries->AddrArray, pZoneInfo->aipSecondaries->AddrCount, PVD_ZONE_SECONDARIES_IP_ADDRESSES_ARRAY ); } if( pZoneInfo->aipNotify != NULL) { Inst.SetProperty( pZoneInfo->aipNotify->AddrArray, pZoneInfo->aipNotify->AddrCount, PVD_ZONE_NOTIFY_IPADDRESSES_ARRAY ); } if( pZoneInfo->aipScavengeServers ) { Inst.SetProperty( pZoneInfo->aipScavengeServers->AddrArray, pZoneInfo->aipScavengeServers->AddrCount, PVD_ZONE_SCAVENGE_SERVERS ); } Inst.SetProperty( pZoneInfo->dwLastSuccessfulSoaCheck, PVD_ZONE_LAST_SOA_CHECK ); Inst.SetProperty( pZoneInfo->dwLastSuccessfulXfr, PVD_ZONE_LAST_GOOD_XFR ); } //clean up DnssrvFreeZoneInfo(pZoneInfo); if( status != ERROR_SUCCESS) { DNS_DEBUG( INSTPROV, ( "%s: server %S zone %S throwing %s\n", fn, wszServer, wszZone, status )); ThrowException(status); } DNS_DEBUG( INSTPROV, ( "%s: server %S zone %S returning WBEM_S_NO_ERROR\n", fn, wszServer, wszZone )); return WBEM_S_NO_ERROR; } SCODE CDnsWrap::dnsSetProperty( const WCHAR* wszZoneName, const char* pszPropertyName, DWORD dwValue ) { char * pszZone = NULL; WcharToChar(wszZoneName, &pszZone); return dnsSetProperty( pszZone, pszPropertyName, dwValue ); } SCODE CDnsWrap::dnsSetProperty( const char* pszZoneName, const char* pszPropertyName, DWORD dwValue ) { DBG_FN( "CDnsWrap::dnsSetDwordProperty" ); DNS_DEBUG( INSTPROV, ( "%s: zone %s property %s value %d\n", fn, pszZoneName, pszPropertyName, dwValue )); LONG status = DnssrvResetDwordProperty( PVD_DNS_LOCAL_SERVER, pszZoneName, pszPropertyName, dwValue ); if ( status != ERROR_SUCCESS ) { DNS_DEBUG( INSTPROV, ( "%s: throwing 0x%X for zone %s property %s\n", fn, status, pszZoneName, pszPropertyName )); ThrowException( status ); } return WBEM_S_NO_ERROR; } SCODE CDnsWrap::dnsQueryProperty( const WCHAR* wszZoneName, const WCHAR* wszPropertyName, DWORD* pdwResult ) { char * szZone = NULL; char * szProp = NULL; WcharToChar(wszZoneName, &szZone); WcharToChar(wszPropertyName, &szProp); LONG status = DnssrvQueryZoneDwordProperty( PVD_DNS_LOCAL_SERVER, szZone, szProp, pdwResult ); delete [] szZone; delete [] szProp; if(status != ERROR_SUCCESS) ThrowException(status); return WBEM_S_NO_ERROR; } SCODE CDnsWrap::dnsResumeZone( const char* strZoneName ) { DNS_STATUS status = DnssrvResumeZone( PVD_DNS_LOCAL_SERVER, strZoneName); if(status != ERROR_SUCCESS) { ThrowException(status); } return WBEM_S_NO_ERROR; } SCODE CDnsWrap::dnsPauseZone( const char *strZoneName ) { int status = DnssrvPauseZone( PVD_DNS_LOCAL_SERVER, strZoneName // zone name ); if ( status != ERROR_SUCCESS ) { ThrowException(status); } return WBEM_S_NO_ERROR; } void CDnsWrap::ThrowException( LONG status) { CDnsProvException dnsExcep(Dns_StatusString(status),status); throw dnsExcep; } void CDnsWrap::ThrowException( LPCSTR ErrString ) { CDnsProvException dnsExcep(ErrString); throw dnsExcep; } SCODE CDnsWrap::dnsClearCache() { DNS_STATUS status = DnssrvOperation( PVD_DNS_LOCAL_SERVER, NULL, DNSSRV_OP_CLEAR_CACHE, DNSSRV_TYPEID_NULL, NULL ); if(status != S_OK) ThrowException(status); return WBEM_S_NO_ERROR; } SCODE CDnsWrap::dnsOperation( string& strZone, //zone name OpsFlag OperationID ) { string strOps; switch(OperationID) { case DNS_WRAP_RELOAD_ZONE: strOps = DNSSRV_OP_ZONE_RELOAD; break; case DNS_WRAP_RESUME_ZONE: strOps = DNSSRV_OP_ZONE_RESUME; break; case DNS_WRAP_PAUSE_ZONE: strOps = DNSSRV_OP_ZONE_PAUSE; break; case DNS_WRAP_DS_UPDATE: strOps = DNSSRV_OP_ZONE_UPDATE_FROM_DS; break; case DNS_WRAP_WRITE_BACK_ZONE: strOps = DNSSRV_OP_ZONE_WRITE_BACK_FILE; break; case DNS_WRAP_REFRESH_SECONDARY: strOps = DNSSRV_OP_ZONE_REFRESH; break; default: return WBEM_E_FAILED; } DNS_STATUS status = DnssrvOperation( PVD_DNS_LOCAL_SERVER, strZone.data(), strOps.data(), DNSSRV_TYPEID_NULL, NULL ); if(status != S_OK) ThrowException(status); return WBEM_S_NO_ERROR; } ///////////////////////////////////////////////////////////////////////////// //++ // // Description: // returns a mapping table that maps wbem property and dns property // , and operation can be performed // on the property such as get and set // // Arguments: // pdwSize [IN ] size of the table // Return Value: // WBEM_S_NO_ERROR // //-- ///////////////////////////////////////////////////////////////////////////// PVOID CDnsWrap::GetPropertyTable( DWORD* pdwSize ) { // // Macros to simplify adding elements to the property array. // #define DECLARE_DW_ELEMENT( str ) \ { \ MYTEXT( str ), \ str, \ dnsSetDwordProperty, \ dnsGetDwordProperty \ } #define DECLARE_STR_ELEMENT( str ) \ { \ MYTEXT( str ), \ str, \ dnsSetStringProperty, \ dnsGetStringProperty \ } #define DECLARE_IPARRAY_ELEMENT( str ) \ { \ MYTEXT( str ), \ str, \ dnsSetIPArrayProperty, \ dnsGetIPArrayProperty \ } // // Array of server properties. // static PropertyTable pt[] = { DECLARE_DW_ELEMENT( DNS_REGKEY_ADDRESS_ANSWER_LIMIT ), DECLARE_DW_ELEMENT( DNS_REGKEY_ALLOW_UPDATE ), DECLARE_DW_ELEMENT( DNS_REGKEY_RPC_PROTOCOL ), DECLARE_DW_ELEMENT( DNS_REGKEY_NO_RECURSION ), DECLARE_DW_ELEMENT( DNS_REGKEY_RECURSION_RETRY ), DECLARE_DW_ELEMENT( DNS_REGKEY_RECURSION_TIMEOUT ), DECLARE_DW_ELEMENT( DNS_REGKEY_FORWARD_TIMEOUT ), DECLARE_DW_ELEMENT( DNS_REGKEY_SLAVE ), DECLARE_DW_ELEMENT( DNS_REGKEY_AUTO_CACHE_UPDATE ), DECLARE_DW_ELEMENT( DNS_REGKEY_DISJOINT_NETS ), DECLARE_DW_ELEMENT( DNS_REGKEY_ROUND_ROBIN ), DECLARE_DW_ELEMENT( DNS_REGKEY_BIND_SECONDARIES ), DECLARE_DW_ELEMENT( DNS_REGKEY_WRITE_AUTHORITY_NS ), DECLARE_DW_ELEMENT( DNS_REGKEY_STRICT_FILE_PARSING ), DECLARE_DW_ELEMENT( DNS_REGKEY_LOOSE_WILDCARDING ), DECLARE_DW_ELEMENT( DNS_REGKEY_EVENTLOG_LEVEL ), DECLARE_DW_ELEMENT( DNS_REGKEY_LOG_LEVEL ), DECLARE_DW_ELEMENT( DNS_REGKEY_MAX_CACHE_TTL ), DECLARE_DW_ELEMENT( DNS_REGKEY_MAX_NEGATIVE_CACHE_TTL ), DECLARE_DW_ELEMENT( DNS_REGKEY_DS_POLLING_INTERVAL ), DECLARE_DW_ELEMENT( DNS_REGKEY_DS_TOMBSTONE_INTERVAL ), DECLARE_DW_ELEMENT( DNS_REGKEY_NAME_CHECK_FLAG ), DECLARE_DW_ELEMENT( DNS_REGKEY_SEND_PORT ), DECLARE_DW_ELEMENT( DNS_REGKEY_BOOT_METHOD ), DECLARE_DW_ELEMENT( DNS_REGKEY_NO_AUTO_REVERSE_ZONES ), DECLARE_DW_ELEMENT( DNS_REGKEY_LOCAL_NET_PRIORITY ), DECLARE_DW_ELEMENT( DNS_REGKEY_FORWARD_DELEGATIONS ), DECLARE_DW_ELEMENT( DNS_REGKEY_SECURE_RESPONSES ), DECLARE_DW_ELEMENT( DNS_REGKEY_AUTO_CONFIG_FILE_ZONES ), DECLARE_DW_ELEMENT( DNS_REGKEY_DEFAULT_AGING_STATE ), DECLARE_DW_ELEMENT( DNS_REGKEY_DEFAULT_REFRESH_INTERVAL ), DECLARE_DW_ELEMENT( DNS_REGKEY_DEFAULT_NOREFRESH_INTERVAL ), DECLARE_DW_ELEMENT( DNS_REGKEY_ENABLE_DNSSEC ), DECLARE_DW_ELEMENT( DNS_REGKEY_ENABLE_EDNS ), DECLARE_DW_ELEMENT( DNS_REGKEY_EDNS_CACHE_TIMEOUT ), DECLARE_DW_ELEMENT( DNS_REGKEY_ENABLE_DP ), DECLARE_DW_ELEMENT( DNS_REGKEY_XFR_CONNECT_TIMEOUT ), DECLARE_DW_ELEMENT( DNS_REGKEY_SCAVENGING_INTERVAL ), DECLARE_DW_ELEMENT( DNS_REGKEY_UPDATE_OPTIONS ), DECLARE_DW_ELEMENT( DNS_REGKEY_LOG_FILE_MAX_SIZE ), DECLARE_STR_ELEMENT( DNS_REGKEY_LOG_FILE_PATH ), DECLARE_IPARRAY_ELEMENT( DNS_REGKEY_LOG_IP_FILTER_LIST ), { MYTEXT( DNS_REGKEY_FORWARDERS ), DNS_REGKEY_FORWARDERS, dnsSetServerForwarders, NULL }, DECLARE_DW_ELEMENT( DNS_REGKEY_FORWARD_TIMEOUT ), DECLARE_DW_ELEMENT( DNS_REGKEY_SLAVE ), { MYTEXT( DNS_REGKEY_LISTEN_ADDRESSES ), DNS_REGKEY_LISTEN_ADDRESSES, dnsSetServerListenAddress, NULL }, }; static DWORD dwNumofElements = sizeof(pt)/sizeof(PropertyTable); *pdwSize = dwNumofElements; return &pt; } SCODE CDnsWrap::dnsZoneCreate( string& strZoneName, DWORD dwZoneType, string& strDataFile, string& strAdmin, DWORD* pIp, DWORD cIp ) { DWORD loadOptions = 0, fuseDs = FALSE; LPSTR pszData = NULL; if(dwZoneType == 2) //secondary zone must supply master ip array { if( cIp <=0 || pIp == NULL) return WBEM_E_INVALID_PARAMETER; } else if(dwZoneType == 0) //dsIntegrated { loadOptions = TRUE; //load existing fuseDs = TRUE; dwZoneType =1; // dsPrimary } if( !strDataFile.empty()) { loadOptions |= DNS_ZONE_LOAD_EXISTING; pszData = (LPSTR) strDataFile.data(); } string strAdminEmail = strAdmin; if(strAdminEmail.empty()) strAdminEmail = "Admin"; DNS_STATUS status; status = DnssrvCreateZone( PVD_DNS_LOCAL_SERVER, //server (char*) strZoneName.data(), //zone dwZoneType, //zone type strAdminEmail.data(), // admin email cIp, // size of master pIp, // master ip loadOptions, // load option fuseDs, //dwDsIntegrated, //fuseDs, pszData, //pszDataFile 0, // timeout for forwarder zone 0 // doNotRecurse flag for forwarder zone ); if ( status != ERROR_SUCCESS ) ThrowException(status); return WBEM_S_NO_ERROR; } SCODE CDnsWrap::dnsZoneChangeType( string& strZone, DWORD dwZoneType, string& strDataFile, string& strAdmin, DWORD* pIp, DWORD cIp ) { //set zone type DWORD dwUseDs=FALSE, dwLoadOptions=TRUE, cMaster=0; if(dwZoneType ==1 && strDataFile.empty()) { ThrowException("DataFile required"); } if( dwZoneType == 2) { // change to secondary zone if(pIp == NULL || cIp <= 0 ) // secondary must have master IP return WBEM_E_INVALID_PARAMETER; } else if (dwZoneType == 0) { if(!strDataFile.empty()) //dsIntegrated doesn't use file return WBEM_E_INVALID_PARAMETER; dwUseDs = TRUE; } DNS_STATUS status; status = DnssrvResetZoneTypeEx( PVD_DNS_LOCAL_SERVER, strZone.data(), dwZoneType, cIp, pIp, dwLoadOptions, dwUseDs, strDataFile.data()); if(status != S_OK) ThrowException(status); return WBEM_S_NO_ERROR; } SCODE CDnsWrap::dnsZoneResetSecondary( string& strZoneName, DWORD dwSecurity, DWORD* pSecondaryIp, DWORD cSecondaryIp, DWORD dwNotify, DWORD * pNotifyIp, DWORD cNotifyIp ) { DNS_STATUS status; DWORD tdwNotifyLevel = ZONE_NOTIFY_ALL; DWORD tdwSecurity = ZONE_SECSECURE_NO_SECURITY; if( dwSecurity <=3 ) { tdwSecurity = dwSecurity; } if( dwNotify <=2) { tdwNotifyLevel = dwNotify; } status = DnssrvResetZoneSecondaries( PVD_DNS_LOCAL_SERVER, strZoneName.data(), tdwSecurity, cSecondaryIp, pSecondaryIp, tdwNotifyLevel, cNotifyIp, pNotifyIp); if ( status != ERROR_SUCCESS ) { ThrowException(status); } return WBEM_S_NO_ERROR; } SCODE CDnsWrap::dnsZoneResetMaster( string& strZoneName, DWORD* pMasterIp, DWORD cMasterIp, DWORD dwLocal ) { DNS_STATUS status; DWORD dwValue = -1; status = DnssrvResetZoneMastersEx( PVD_DNS_LOCAL_SERVER, strZoneName.data(), cMasterIp, pMasterIp, dwLocal ); if ( status != ERROR_SUCCESS ) { ThrowException(status); } return WBEM_S_NO_ERROR; } SCODE CDnsWrap::dnsZonePut( CWbemClassObject& Inst ) /*++ Routine Description: This function commits all of the property values in a zone object to the DNS server. Arguments: Inst -- zone object Return Value: S_OK on success. --*/ { DBG_FN( "CDnsWrap::dnsZonePut" ) SCODE sc; DNS_STATUS status = ERROR_SUCCESS; DWORD dwProperty = 0; DWORD dwZoneType = -1; DWORD * dwArray = NULL; DWORD dwArraySize = 0; string strZoneName; string strDataFile; DWORD dwValue; #define DNS_CHECK_STATUS() if ( status != ERROR_SUCCESS ) goto Done // // Get basic properties of the new zone. // Inst.GetProperty( strZoneName, PVD_DOMAIN_CONTAINER_NAME ); Inst.GetProperty( &dwZoneType, PVD_ZONE_ZONE_TYPE ); DNS_DEBUG( INSTPROV, ( "%s: zone %s\n", fn, strZoneName.c_str() )); // // Retrieve properties from the class object and set values // to the server. // if( dwZoneType == DNS_ZONE_TYPE_PRIMARY && Inst.GetProperty( &dwProperty, PVD_ZONE_ALLOW_UPDATE ) == S_OK ) { status = dnsSetProperty( strZoneName.data(), DNS_REGKEY_ZONE_ALLOW_UPDATE, dwProperty ); DNS_CHECK_STATUS(); } if( Inst.GetProperty( &dwProperty, PVD_ZONE_REFRESH_INTERVAL ) == S_OK ) { status = dnsSetProperty( strZoneName.data(), DNS_REGKEY_ZONE_REFRESH_INTERVAL, dwProperty ); DNS_CHECK_STATUS(); } if( Inst.GetProperty( &dwProperty, PVD_ZONE_NOREFRESH_INTERVAL ) == S_OK ) { status = dnsSetProperty( strZoneName.data(), DNS_REGKEY_ZONE_NOREFRESH_INTERVAL, dwProperty ); DNS_CHECK_STATUS(); } status = dnsSetIPArrayProperty( strZoneName.data(), MYTEXT( DNS_REGKEY_ZONE_MASTERS ), DNS_REGKEY_ZONE_MASTERS, Inst ); DNS_CHECK_STATUS(); status = dnsSetIPArrayProperty( strZoneName.data(), MYTEXT( DNS_REGKEY_ZONE_LOCAL_MASTERS ), DNS_REGKEY_ZONE_LOCAL_MASTERS, Inst ); DNS_CHECK_STATUS(); status = dnsSetIPArrayProperty( strZoneName.data(), MYTEXT( DNS_REGKEY_ZONE_SCAVENGE_SERVERS ), DNS_REGKEY_ZONE_SCAVENGE_SERVERS, Inst ); DNS_CHECK_STATUS(); // // Forwarder zone properties. // if ( dwZoneType == DNS_ZONE_TYPE_FORWARDER ) { if( Inst.GetProperty( &dwProperty, MYTEXT( DNS_REGKEY_ZONE_FWD_SLAVE ) ) == S_OK ) { status = dnsSetProperty( strZoneName.data(), DNS_REGKEY_ZONE_FWD_SLAVE, dwProperty ); DNS_CHECK_STATUS(); } if( Inst.GetProperty( &dwProperty, MYTEXT( DNS_REGKEY_ZONE_FWD_TIMEOUT ) ) == S_OK ) { status = dnsSetProperty( strZoneName.data(), DNS_REGKEY_ZONE_FWD_TIMEOUT, dwProperty ); DNS_CHECK_STATUS(); } } // // To handle the zone data file, call DnssrvResetZoneDatabase // dwValue = 0; DnssrvQueryDwordProperty( PVD_DNS_LOCAL_SERVER, strZoneName.data(), DNS_REGKEY_ZONE_DS_INTEGRATED, &dwValue ); if( Inst.GetProperty( strDataFile, PVD_ZONE_DATA_FILE ) == S_OK ) { if( status == S_OK && dwZoneType != 0 && !strDataFile.empty() ) { status = DnssrvResetZoneDatabase( PVD_DNS_LOCAL_SERVER, strZoneName.data(), dwValue, strDataFile.data() ); DNS_CHECK_STATUS(); } } Done: if ( status != ERROR_SUCCESS ) { DNS_DEBUG( INSTPROV, ( "%s: zone %s throwing %d\n", fn, strZoneName.c_str(), status )); ThrowException( status ); } DNS_DEBUG( INSTPROV, ( "%s: zone %s returning WBEM_S_NO_ERROR\n", fn, strZoneName.c_str() )); return WBEM_S_NO_ERROR; #undef DNS_CHECK_STATUS } static SCODE dnsWrapCreateStatistic( IWbemClassObject * pClass, IWbemObjectSink * pHandler, DWORD dwStatCollection, const WCHAR * pszStatisticName, CIMTYPE cimType, const void * value ) /*++ Routine Description: Creates and populates a single DNS statistic object. Arguments: pClass -- MicrosoftDNS_Statistic class object used to spawn new instance dwStatCollection -- index into global collection array pszStatisticName -- statistic name cimType - type of statistic VT_UI4: value is a DWORD VT_BSTR: value is a pointer to a string value - interpret as per cimType Return Value: S_OK or error code. --*/ { CDnsWrap & dns = CDnsWrap::DnsObject(); CWbemClassObject Inst; pClass->SpawnInstance( 0, &Inst); Inst.SetProperty( dns.GetServerName(), PVD_DOMAIN_SERVER_NAME ); Inst.SetProperty( g_StatInfo[ dwStatCollection ].pszName, L"CollectionName" ); Inst.SetProperty( g_StatInfo[ dwStatCollection ].dwStatId, L"CollectionId" ); Inst.SetProperty( pszStatisticName, L"Name" ); if ( cimType == VT_BSTR ) { Inst.SetProperty( ( LPCWSTR ) value, L"StringValue" ); } else { DWORD dw = ( DWORD ) ( DWORD_PTR ) value; Inst.SetProperty( dw, L"Value" ); } pHandler->Indicate( 1, &Inst ); return S_OK; } // dnsWrapCreateStatistic static SCODE dnsWrapAddStatisticsForTypeArray( IWbemClassObject * pClass, IWbemObjectSink * pHandler, DWORD statCollIdx, PWSTR pszHeader, PDWORD pArray ) /*++ Routine Description: Adds DWORD statistics for each member of a type array. Arguments: pClass -- WMI statistic class pHandler -- WMI object sink statCollIdx -- index into global stat information array pszHeader -- header text used to format statistic description pArray -- array of DWORDs for types Return Value: None --*/ { WCHAR sz[ 80 ]; #define dwStat( pwszName, dwValue ) \ dnsWrapCreateStatistic( \ pClass, \ pHandler, \ statCollIdx, \ pwszName, \ VT_UI4, \ ( void * ) ( DWORD_PTR ) ( dwValue ) ); for ( DWORD i = 0; i < STATS_TYPE_MAX; i++ ) { if ( i == STATS_TYPE_MIXED || i == STATS_TYPE_UNKNOWN ) { continue; } wsprintfW( sz, L"%s for %S type", pszHeader, Dns_RecordStringForType( ( WORD ) i ) ); dwStat( sz, pArray[ i ] ); } wsprintfW( sz, L"%s for unknown type", pszHeader ); dwStat( sz, pArray[ STATS_TYPE_UNKNOWN ] ); wsprintfW( sz, L"%s for mixed type", pszHeader ); dwStat( sz, pArray[ STATS_TYPE_MIXED ] ); #undef dwStat return S_OK; } // dnsWrapAddStatisticsForTypeArray static SCODE dnsWrapHandleSingleStat( IWbemClassObject * pClass, IWbemObjectSink * pHandler, PDNSSRV_STAT pStat ) /*++ Routine Description: Process a single statistic buffer by creating Statistic object instances for each of the members of the stat buffer. Arguments: pClass -- WMI statistic class pHandler -- WMI object sink pStat -- buffer of stats to process Return Value: None --*/ { SCODE sc = S_OK; const int szBufferLen = 254; WCHAR szBuffer[ szBufferLen ]; SAFEARRAY * psa = NULL; SAFEARRAYBOUND rgsabound[ 1 ] = { 0, 0 }; int statCollIdx = -1; // // Get index into g_StatInfo element for this stat. // for ( int i = 0; g_StatInfo[ i ].dwStatId != 0 && g_StatInfo[ i ].dwStatId != pStat->Header.StatId; ++i ); if ( g_StatInfo[ i ].dwStatId != 0 ) { statCollIdx = i; } // // Macros to creating individual stat objects. // #define strStat( pwszName, pwszValue ) \ dnsWrapCreateStatistic( \ pClass, \ pHandler, \ statCollIdx, \ pwszName, \ VT_BSTR, \ pwszValue ); #define dwStat( pwszName, dwValue ) \ dnsWrapCreateStatistic( \ pClass, \ pHandler, \ statCollIdx, \ pwszName, \ VT_UI4, \ ( void * ) ( DWORD_PTR ) ( dwValue ) ); // // Process the individual statistics in this stat collection. // switch ( pStat->Header.StatId ) { case DNSSRV_STATID_TIME: { PDNSSRV_TIME_STATS pstat = ( PDNSSRV_TIME_STATS ) pStat; SYSTEMTIME localTime; SystemTimeToTzSpecificLocalTime( NULL, ( PSYSTEMTIME ) &pstat->ServerStartTime, &localTime ); GetDateFormatW( LOCALE_SYSTEM_DEFAULT, LOCALE_NOUSEROVERRIDE, &localTime, NULL, szBuffer, szBufferLen ); wcscat( szBuffer, L" " ); GetTimeFormatW( LOCALE_SYSTEM_DEFAULT, LOCALE_NOUSEROVERRIDE, &localTime, NULL, szBuffer + wcslen( szBuffer ), szBufferLen - wcslen( szBuffer ) ); strStat( L"Server started", szBuffer ); SystemTimeToTzSpecificLocalTime( NULL, ( PSYSTEMTIME ) &pstat->LastClearTime, &localTime ); GetDateFormatW( LOCALE_SYSTEM_DEFAULT, LOCALE_NOUSEROVERRIDE, &localTime, NULL, szBuffer, szBufferLen ); wcscat( szBuffer, L" " ); GetTimeFormatW( LOCALE_SYSTEM_DEFAULT, LOCALE_NOUSEROVERRIDE, &localTime, NULL, szBuffer + wcslen( szBuffer ), szBufferLen - wcslen( szBuffer ) ); strStat( L"Statistics last cleared", szBuffer ); break; } case DNSSRV_STATID_QUERY: { PDNSSRV_QUERY_STATS pstat = ( PDNSSRV_QUERY_STATS ) pStat; dwStat( L"Queries received", pstat->UdpQueries + pstat->TcpQueries ); dwStat( L"Responses sent", pstat->UdpResponses + pstat->TcpResponses ); dwStat( L"UDP queries received", pstat->UdpQueries ); dwStat( L"UDP responses sent", pstat->UdpResponses ); dwStat( L"UDP queries sent", pstat->UdpQueriesSent ); dwStat( L"UDP responses received", pstat->UdpResponsesReceived ); dwStat( L"TCP client connections", pstat->TcpClientConnections ); dwStat( L"TCP queries received", pstat->TcpQueries ); dwStat( L"TCP responses sent", pstat->TcpResponses ); dwStat( L"TCP queries sent", pstat->TcpQueriesSent ); dwStat( L"TCP responses received", pstat->TcpResponsesReceived ); break; } case DNSSRV_STATID_QUERY2: { PDNSSRV_QUERY2_STATS pstat = ( PDNSSRV_QUERY2_STATS ) pStat; dwStat( L"Total queries", pstat->TotalQueries ); dwStat( L"Notify queries", pstat->Notify ); dwStat( L"Update queries", pstat->Update ); dwStat( L"TKeyNego queries", pstat->TKeyNego ); dwStat( L"Standard queries", pstat->Standard ); dwStat( L"A queries", pstat->TypeA ); dwStat( L"NS queries", pstat->TypeNs ); dwStat( L"SOA queries", pstat->TypeSoa ); dwStat( L"MX queries", pstat->TypeMx ); dwStat( L"PTR queries", pstat->TypePtr ); dwStat( L"SRV queries", pstat->TypeSrv ); dwStat( L"ALL queries", pstat->TypeAll ); dwStat( L"IXFR queries", pstat->TypeIxfr ); dwStat( L"AXFR queries", pstat->TypeAxfr ); dwStat( L"Other queries", pstat->TypeOther ); break; } case DNSSRV_STATID_RECURSE: { PDNSSRV_RECURSE_STATS pstat = ( PDNSSRV_RECURSE_STATS ) pStat; dwStat( L"Queries recursed", pstat->QueriesRecursed ); dwStat( L"Original questions recursed", pstat->OriginalQuestionRecursed ); dwStat( L"Additional questions recursed", pstat->AdditionalRecursed ); dwStat( L"Total questions recursed", pstat->TotalQuestionsRecursed ); dwStat( L"Original questions recursed", pstat->OriginalQuestionRecursed ); dwStat( L"Retries", pstat->Retries ); dwStat( L"Total passes", pstat->LookupPasses ); dwStat( L"To forwarders", pstat->Forwards ); dwStat( L"Sends", pstat->Sends ); dwStat( L"Total responses", pstat->Responses ); dwStat( L"Responses unmatched", pstat->ResponseUnmatched ); dwStat( L"Responses mismatched", pstat->ResponseMismatched ); dwStat( L"Responses from forwarders", pstat->ResponseFromForwarder ); dwStat( L"Authoritative responses", pstat->ResponseAuthoritative ); dwStat( L"NotAuthoritative responses", pstat->ResponseNotAuth ); dwStat( L"Answer responses", pstat->ResponseAnswer ); dwStat( L"Empty responses", pstat->ResponseEmpty ); dwStat( L"Name error responses", pstat->ResponseAnswer ); dwStat( L"Rcode responses", pstat->ResponseRcode ); dwStat( L"Delegation responses", pstat->ResponseDelegation ); dwStat( L"Non-zone data responses", pstat->ResponseNonZoneData ); dwStat( L"Unsecure responses", pstat->ResponseUnsecure ); dwStat( L"Bad packet responses", pstat->ResponseBadPacket ); dwStat( L"Forwarded responses", pstat->SendResponseDirect ); dwStat( L"Continue current recursion responses", pstat->ContinueCurrentRecursion ); dwStat( L"Continue current lookup responses", pstat->ContinueCurrentLookup ); dwStat( L"Continue next lookup responses", pstat->ContinueNextLookup ); dwStat( L"Send timeouts", pstat->PacketTimeout ); dwStat( L"Final queued timeouts", pstat->FinalTimeoutQueued ); dwStat( L"Final timeouts expired", pstat->FinalTimeoutExpired ); dwStat( L"Recurse failures", pstat->RecursePassFailure ); dwStat( L"Into authority failures", pstat->FailureReachAuthority ); dwStat( L"Previous zone failures", pstat->FailureReachPreviousResponse ); dwStat( L"Retry count failures", pstat->FailureRetryCount ); dwStat( L"Cache update failures", pstat->CacheUpdateFailure ); dwStat( L"Server failure responses", pstat->ServerFailure ); dwStat( L"Total failures", pstat->Failures ); dwStat( L"TCP recursions tried", pstat->TcpTry ); dwStat( L"TCP recursion queries", pstat->TcpQuery ); dwStat( L"TCP recursion responses", pstat->TcpResponse ); dwStat( L"TCP recursion disconnects", pstat->TcpDisconnect ); dwStat( L"Cache update queries allocated", pstat->CacheUpdateAlloc ); dwStat( L"Cache update query responses", pstat->CacheUpdateResponse ); dwStat( L"Cache update query retries", pstat->CacheUpdateRetry ); dwStat( L"Cache update queries freed", pstat->CacheUpdateFree ); dwStat( L"Cache update queries for root NS", pstat->RootNsQuery ); dwStat( L"Cache update responses for root NS", pstat->RootNsResponse ); dwStat( L"Cache update queries suspended", pstat->SuspendedQuery ); dwStat( L"Cache update queries resumed", pstat->ResumeSuspendedQuery ); break; } case DNSSRV_STATID_MASTER: { PDNSSRV_MASTER_STATS pstat = ( PDNSSRV_MASTER_STATS ) pStat; dwStat( L"Notifies sent", pstat->NotifySent ); dwStat( L"Requests", pstat->Request ); dwStat( L"NameErrors", pstat->NameError ); dwStat( L"FormErrors", pstat->FormError ); dwStat( L"Refused", pstat->Refused ); dwStat( L"AxfrLimit refused", pstat->AxfrLimit ); dwStat( L"Security refused", pstat->RefuseSecurity ); dwStat( L"Shutdown refused", pstat->RefuseShutdown ); dwStat( L"ServFail refused", pstat->RefuseServerFailure ); dwStat( L"Transfer failures", pstat->Failure ); dwStat( L"Transfer successes", pstat->AxfrSuccess + pstat->IxfrUpdateSuccess ); dwStat( L"AXFR requests", pstat->AxfrRequest ); dwStat( L"AXFR successes", pstat->AxfrSuccess ); dwStat( L"AXFR in IXFR", pstat->IxfrAxfr ); dwStat( L"IXFR requests", pstat->IxfrRequest ); dwStat( L"IXFR successes", pstat->IxfrUpdateSuccess ); dwStat( L"IXFR UDP requests", pstat->IxfrUdpRequest ); dwStat( L"IXFR UDP successes", pstat->IxfrUdpSuccess ); dwStat( L"IXFR UDP force TCP", pstat->IxfrUdpForceTcp ); dwStat( L"IXFR UDP force AXFR", pstat->IxfrUdpForceAxfr ); dwStat( L"IXFR TCP requests", pstat->IxfrTcpRequest ); dwStat( L"IXFR TCP successes", pstat->IxfrTcpSuccess ); dwStat( L"IXFR TCP force AXFR", pstat->IxfrAxfr ); break; } case DNSSRV_STATID_SECONDARY: { PDNSSRV_SECONDARY_STATS pstat = (PDNSSRV_SECONDARY_STATS)pStat; dwStat( L"Notifies received", pstat->NotifyReceived ); dwStat( L"Notifies invalid", pstat->NotifyInvalid ); dwStat( L"Notifies primary", pstat->NotifyPrimary ); dwStat( L"Notifies no version", pstat->NotifyNoVersion ); dwStat( L"Notifies new version", pstat->NotifyNewVersion ); dwStat( L"Notifies current version", pstat->NotifyCurrentVersion ); dwStat( L"Notifies old version", pstat->NotifyOldVersion ); dwStat( L"Notifies master unknown", pstat->NotifyMasterUnknown ); dwStat( L"SOA requests", pstat->SoaRequest ); dwStat( L"SOA responses", pstat->SoaResponse ); dwStat( L"SOA invalid responses", pstat->SoaResponseInvalid ); dwStat( L"SOA NameError responses", pstat->SoaResponseNameError ); dwStat( L"AXFR requests", pstat->AxfrRequest ); dwStat( L"AXFR in IXFR requests", pstat->IxfrTcpAxfr ); dwStat( L"AXFR responses", pstat->AxfrResponse ); dwStat( L"AXFR success responses", pstat->AxfrSuccess ); dwStat( L"AXFR refused responses", pstat->AxfrRefused ); dwStat( L"AXFR invalid responses", pstat->AxfrInvalid ); dwStat( L"Stub zone AXFR requests", pstat->StubAxfrRequest ); dwStat( L"Stub zone AXFR responses", pstat->StubAxfrResponse ); dwStat( L"Stub zone AXFR success responses", pstat->StubAxfrSuccess ); dwStat( L"Stub zone AXFR refused responses", pstat->StubAxfrRefused ); dwStat( L"Stub zone AXFR invalid responses", pstat->StubAxfrInvalid ); dwStat( L"IXFR UDP requests", pstat->IxfrUdpRequest ); dwStat( L"IXFR UDP responses", pstat->IxfrUdpResponse ); dwStat( L"IXFR UDP success responses", pstat->IxfrUdpSuccess ); dwStat( L"IXFR UDP UseTcp responses", pstat->IxfrUdpUseTcp ); dwStat( L"IXFR UDP UseAxfr responses", pstat->IxfrUdpUseAxfr ); dwStat( L"IXFR UDP new primary responses", pstat->IxfrUdpNewPrimary ); dwStat( L"IXFR UDP refused responses", pstat->IxfrUdpRefused ); dwStat( L"IXFR UDP wrong server responses", pstat->IxfrUdpWrongServer ); dwStat( L"IXFR UDP FormError responses", pstat->IxfrUdpFormerr ); dwStat( L"IXFR UDP invalid responses", pstat->IxfrUdpInvalid ); dwStat( L"IXFR TCP requests", pstat->IxfrTcpRequest ); dwStat( L"IXFR TCP responses", pstat->IxfrTcpResponse ); dwStat( L"IXFR TCP success responses", pstat->IxfrTcpSuccess ); dwStat( L"IXFR TCP AXFR responses", pstat->IxfrTcpAxfr ); dwStat( L"IXFR TCP FormError responses", pstat->IxfrTcpFormerr ); dwStat( L"IXFR TCP refused responses", pstat->IxfrTcpRefused ); dwStat( L"IXFR TCP invalid responses", pstat->IxfrTcpInvalid ); break; } case DNSSRV_STATID_WINS: { PDNSSRV_WINS_STATS pstat = ( PDNSSRV_WINS_STATS ) pStat; dwStat( L"WINS forward lookups", pstat->WinsLookups ); dwStat( L"WINS forward lookup responses", pstat->WinsResponses ); dwStat( L"WINS reverse lookups", pstat->WinsReverseLookups ); dwStat( L"WINS reverse lookup responses", pstat->WinsReverseResponses ); break; } case DNSSRV_STATID_NBSTAT: { PDNSSRV_NBSTAT_STATS pstat = (PDNSSRV_NBSTAT_STATS)pStat; dwStat( L"Nbstat total buffers allocated", pstat->NbstatAlloc ); dwStat( L"Nbstat total buffers freed", pstat->NbstatFree ); dwStat( L"Nbstat net buffers allocated", pstat->NbstatNetAllocs ); dwStat( L"Nbstat net bytes allocated", pstat->NbstatMemory ); dwStat( L"Nbstat memory highwater mark", pstat->NbstatUsed ); dwStat( L"Nbstat buffers returned", pstat->NbstatReturn ); dwStat( L"Nbstat buffers in use", pstat->NbstatInUse ); dwStat( L"Nbstat buffers on free list", pstat->NbstatInFreeList ); break; } case DNSSRV_STATID_WIRE_UPDATE: case DNSSRV_STATID_NONWIRE_UPDATE: { PDNSSRV_UPDATE_STATS pstat = ( PDNSSRV_UPDATE_STATS ) pStat; dwStat( L"Updates received", pstat->Received ); dwStat( L"Updates forwarded", pstat->Forwards ); dwStat( L"Updates retried", pstat->Retry ); dwStat( L"Updates empty (precon only)", pstat->Empty ); dwStat( L"Updates NoOps (duplicates)", pstat->NoOps ); dwStat( L"Updates rejected", pstat->Rejected ); dwStat( L"Updates completed", pstat->Completed ); dwStat( L"Updates timed out", pstat->Timeout ); dwStat( L"Updates in queue", pstat->InQueue ); dwStat( L"Updates rejected", pstat->Rejected ); dwStat( L"Updates rejected with FormError", pstat->FormErr ); dwStat( L"Updates rejected with NameError", pstat->NxDomain ); dwStat( L"Updates rejected with NotImpl", pstat->NotImpl ); dwStat( L"Updates rejected with Refused", pstat->Refused ); dwStat( L"Updates rejected with Refused (nonsecure)", pstat->RefusedNonSecure ); dwStat( L"Updates rejected with Refused (access denied)", pstat->RefusedAccessDenied ); dwStat( L"Updates rejected with YxDomain", pstat->YxDomain ); dwStat( L"Updates rejected with YxRRSet", pstat->YxRrset ); dwStat( L"Updates rejected with NxRRSet", pstat->NxRrset ); dwStat( L"Updates rejected with NotAuth", pstat->NotAuth ); dwStat( L"Updates rejected with NotZone", pstat->NotZone ); dwStat( L"Secure update successes", pstat->SecureSuccess ); dwStat( L"Secure update continues", pstat->SecureContinue ); dwStat( L"Secure update failures", pstat->SecureFailure ); dwStat( L"Secure update DS write failures", pstat->SecureDsWriteFailure ); dwStat( L"Updates forwarded via TCP", pstat->TcpForwards ); dwStat( L"Responses for forwarded updates", pstat->ForwardResponses ); dwStat( L"Timeouts for forwarded updates", pstat->ForwardTimeouts ); dwStat( L"Forwarded updates in queue", pstat->ForwardInQueue ); dnsWrapAddStatisticsForTypeArray( pClass, pHandler, statCollIdx, L"Updates", pstat->UpdateType ); break; } case DNSSRV_STATID_DS: { PDNSSRV_DS_STATS pstat = ( PDNSSRV_DS_STATS ) pStat; dwStat( L"Nodes read", pstat->DsTotalNodesRead ); dwStat( L"Records read", pstat->DsTotalRecordsRead ); dwStat( L"Nodes loaded", pstat->DsNodesLoaded ); dwStat( L"Records loaded", pstat->DsRecordsLoaded ); dwStat( L"Update searches", pstat->DsUpdateSearches ); dwStat( L"Update nodes read", pstat->DsUpdateNodesRead ); dwStat( L"Update records read", pstat->DsUpdateRecordsRead ); dwStat( L"Nodes added", pstat->DsNodesAdded ); dwStat( L"Nodes modified", pstat->DsNodesModified ); dwStat( L"Nodes tombstoned", pstat->DsNodesTombstoned ); dwStat( L"Tombstones read", pstat->DsTombstonesRead ); dwStat( L"Nodes deleted", pstat->DsNodesDeleted ); dwStat( L"Nodes write suppressed", pstat->DsWriteSuppressed ); dwStat( L"RR sets added", pstat->DsRecordsAdded ); dwStat( L"RR sets replaced", pstat->DsRecordsReplaced ); dwStat( L"Serial number writes", pstat->DsSerialWrites ); dwStat( L"Update lists", pstat->UpdateLists ); dwStat( L"Update nodes", pstat->UpdateNodes ); dwStat( L"Updates suppressed ", pstat->UpdateSuppressed ); dwStat( L"Update writes", pstat->UpdateWrites ); dwStat( L"Update tombstones", pstat->UpdateTombstones ); dwStat( L"Update record changes", pstat->UpdateRecordChange ); dwStat( L"Update aging refresh", pstat->UpdateAgingRefresh ); dwStat( L"Update aging on", pstat->UpdateAgingOn ); dwStat( L"Update aging off", pstat->UpdateAgingOff ); dwStat( L"Update from packet", pstat->UpdatePacket ); dwStat( L"Update from packet (precon)", pstat->UpdatePacketPrecon ); dwStat( L"Update from admin", pstat->UpdateAdmin ); dwStat( L"Update from auto config", pstat->UpdateAutoConfig ); dwStat( L"Update from scavenge", pstat->UpdateScavenge ); dwStat( L"LDAP timed writes", pstat->LdapTimedWrites ); dwStat( L"LDAP total write time", pstat->LdapWriteTimeTotal ); dwStat( L"LDAP average write time", pstat->LdapWriteAverage ); dwStat( L"LDAP writes < 10 ms", pstat->LdapWriteBucket0 ); dwStat( L"LDAP writes < 100 ms", pstat->LdapWriteBucket1 ); dwStat( L"LDAP writes < 1 s", pstat->LdapWriteBucket2 ); dwStat( L"LDAP writes < 10 s", pstat->LdapWriteBucket3 ); dwStat( L"LDAP writes < 100 s", pstat->LdapWriteBucket4 ); dwStat( L"LDAP writes > 100 s", pstat->LdapWriteBucket5 ); dwStat( L"LDAP writes max timeout", pstat->LdapWriteMax ); dwStat( L"Total LDAP search time", pstat->LdapSearchTime ); dwStat( L"Failed deletions", pstat->FailedDeleteDsEntries ); dwStat( L"Failed reads", pstat->FailedReadRecords ); dwStat( L"Failed modifies", pstat->FailedLdapModify ); dwStat( L"Failed adds", pstat->FailedLdapAdd ); dwStat( L"Polling passes with DS errors", pstat->PollingPassesWithDsErrors ); dnsWrapAddStatisticsForTypeArray( pClass, pHandler, statCollIdx, L"LDAP writes", pstat->DsWriteType ); break; } case DNSSRV_STATID_SKWANSEC: { PDNSSRV_SKWANSEC_STATS pstat = ( PDNSSRV_SKWANSEC_STATS ) pStat; dwStat( L"Security contexts created", pstat->SecContextCreate ); dwStat( L"Security contexts freed", pstat->SecContextFree ); dwStat( L"Security contexts timed out", pstat->SecContextTimeout ); dwStat( L"Security contexts queue length", pstat->SecContextQueueLength ); dwStat( L"Security contexts queued", pstat->SecContextQueue ); dwStat( L"Security contexts queued in negotiation", pstat->SecContextQueueInNego ); dwStat( L"Security contexts queued negotiation complete", pstat->SecContextQueueNegoComplete ); dwStat( L"Security contexts dequeued", pstat->SecContextDequeue ); dwStat( L"Security packet contexts allocated", pstat->SecPackAlloc ); dwStat( L"Security packet contexts freed", pstat->SecPackFree ); dwStat( L"Invalid TKEYs", pstat->SecTkeyInvalid ); dwStat( L"Bad time TKEYs", pstat->SecTkeyBadTime ); dwStat( L"FormErr TSIGs", pstat->SecTsigFormerr ); dwStat( L"Echo TSIGs", pstat->SecTsigEcho ); dwStat( L"BadKey TSIGs", pstat->SecTsigBadKey ); dwStat( L"Verify success TSIGs", pstat->SecTsigVerifySuccess ); dwStat( L"Verify failed TSIGs", pstat->SecTsigVerifyFailed ); break; } case DNSSRV_STATID_MEMORY: { PDNSSRV_MEMORY_STATS pstat = ( PDNSSRV_MEMORY_STATS ) pStat; LPSTR * pnameArray = MemTagStrings; DWORD count = MEMTAG_COUNT; dwStat( L"Total memory", pstat->StdUsed ); dwStat( L"Allocation count", pstat->Alloc ); dwStat( L"Free count", pstat->Free ); dwStat( L"Standard allocs used", pstat->StdUsed ); dwStat( L"Standard allocs returned", pstat->StdReturn ); dwStat( L"Standard allocs in use", pstat->StdInUse ); dwStat( L"Standard allocs memory", pstat->StdMemory ); dwStat( L"Standard to heap allocs used", pstat->StdToHeapAlloc ); dwStat( L"Standard to heap allocs returned", pstat->StdToHeapFree ); dwStat( L"Standard to heap allocs in use", pstat->StdToHeapInUse ); dwStat( L"Standard to heap allocs memory", pstat->StdToHeapMemory ); dwStat( L"Standard blocks allocated", pstat->StdBlockAlloc ); dwStat( L"Standard blocks used", pstat->StdBlockUsed ); dwStat( L"Standard blocks returned", pstat->StdBlockReturn ); dwStat( L"Standard blocks in use", pstat->StdBlockInUse ); dwStat( L"Standard blocks in free list", pstat->StdBlockFreeList ); dwStat( L"Standard block memory in free list", pstat->StdBlockFreeListMemory ); dwStat( L"Standard block total memory", pstat->StdBlockMemory ); for ( DWORD i = 0; i < count; ++i ) { WCHAR sz[ 80 ]; wsprintfW( sz, L"%S blocks allocated", pnameArray[ i ] ); dwStat( sz, pstat->MemTags[ i ].Alloc ); wsprintfW( sz, L"%S blocks freed", pnameArray[ i ] ); dwStat( sz, pstat->MemTags[ i ].Free ); wsprintfW( sz, L"%S blocks in use", pnameArray[ i ] ); dwStat( sz, pstat->MemTags[ i ].Alloc - pstat->MemTags[ i ].Free ); wsprintfW( sz, L"%S memory", pnameArray[ i ] ); dwStat( sz, pstat->MemTags[ i ].Memory ); } break; } case DNSSRV_STATID_DBASE: { PDNSSRV_DBASE_STATS pstat = ( PDNSSRV_DBASE_STATS ) pStat; dwStat( L"Database nodes used", pstat->NodeUsed ); dwStat( L"Database nodes returned", pstat->NodeReturn ); dwStat( L"Database nodes in use", pstat->NodeInUse ); dwStat( L"Database nodes memory", pstat->NodeMemory ); break; } case DNSSRV_STATID_RECORD: { PDNSSRV_RECORD_STATS pstat = ( PDNSSRV_RECORD_STATS ) pStat; dwStat( L"Records used", pstat->Used ); dwStat( L"Records returned", pstat->Return ); dwStat( L"Records in use", pstat->InUse ); dwStat( L"Records memory", pstat->Memory ); dwStat( L"Records queued for slow free", pstat->SlowFreeQueued ); dwStat( L"Records slow freed", pstat->SlowFreeFinished ); dwStat( L"Total records cached", pstat->CacheTotal ); dwStat( L"Records currently cached", pstat->CacheCurrent ); dwStat( L"Cached records timed out", pstat->CacheTimeouts ); break; } case DNSSRV_STATID_PACKET: { PDNSSRV_PACKET_STATS pstat = ( PDNSSRV_PACKET_STATS ) pStat; dwStat( L"UDP messages allocated", pstat->UdpAlloc ); dwStat( L"UDP messages freed", pstat->UdpFree ); dwStat( L"UDP messages net allocations", pstat->UdpNetAllocs ); dwStat( L"UDP messages memory", pstat->UdpMemory ); dwStat( L"UDP messages used", pstat->UdpUsed ); dwStat( L"UDP messages returned", pstat->UdpReturn ); dwStat( L"UDP messages in use", pstat->UdpInUse ); dwStat( L"UDP messages in free list", pstat->UdpInFreeList ); dwStat( L"UDP messages allocated", pstat->TcpAlloc ); dwStat( L"UDP messages reallocated", pstat->TcpRealloc ); dwStat( L"UDP messages freed", pstat->TcpFree ); dwStat( L"UDP messages net allocations", pstat->TcpNetAllocs ); dwStat( L"UDP messages memory", pstat->TcpMemory ); dwStat( L"Recursion messages used", pstat->RecursePacketUsed ); dwStat( L"Recursion messages returned", pstat->RecursePacketReturn ); break; } case DNSSRV_STATID_TIMEOUT: { PDNSSRV_TIMEOUT_STATS pstat = ( PDNSSRV_TIMEOUT_STATS ) pStat; dwStat( L"Nodes queued", pstat->SetTotal ); dwStat( L"Nodes directed queued", pstat->SetDirect ); dwStat( L"Nodes queued from reference", pstat->SetFromDereference ); dwStat( L"Nodes queued from child delete", pstat->SetFromChildDelete ); dwStat( L"Nodes duplicate (already queued)", pstat->AlreadyInSystem ); dwStat( L"Nodes checked", pstat->Checks ); dwStat( L"Recent access nodes checked", pstat->RecentAccess ); dwStat( L"Active record nodes checked", pstat->ActiveRecord ); dwStat( L"Can not delete nodes checked", pstat->CanNotDelete ); dwStat( L"Deleted nodes checked", pstat->Deleted ); dwStat( L"Timeout blocks created", pstat->ArrayBlocksCreated ); dwStat( L"Timeout blocks deleted", pstat->ArrayBlocksDeleted ); dwStat( L"Delayed frees queued", pstat->DelayedFreesQueued ); dwStat( L"Delayed frees queued with function", pstat->DelayedFreesQueuedWithFunction ); dwStat( L"Delayed frees executed", pstat->DelayedFreesExecuted ); dwStat( L"Delayed frees executed with function", pstat->DelayedFreesExecutedWithFunction ); break; } case DNSSRV_STATID_ERRORS: { PDNSSRV_ERROR_STATS pstat = ( PDNSSRV_ERROR_STATS ) pStat; dwStat( L"NoError", pstat->NoError ); dwStat( L"FormError", pstat->FormError ); dwStat( L"ServFail", pstat->ServFail ); dwStat( L"NxDomain", pstat->NxDomain ); dwStat( L"NotImpl", pstat->NotImpl ); dwStat( L"Refused", pstat->Refused ); dwStat( L"YxDomain", pstat->YxDomain ); dwStat( L"YxRRSet", pstat->YxRRSet ); dwStat( L"NxRRSet", pstat->NxRRSet ); dwStat( L"NotAuth", pstat->NotAuth ); dwStat( L"NotZone", pstat->NotZone ); dwStat( L"Max", pstat->Max ); dwStat( L"BadSig", pstat->BadSig ); dwStat( L"BadKey", pstat->BadKey ); dwStat( L"BadTime", pstat->BadTime ); dwStat( L"UnknownError", pstat->UnknownError ); break; } case DNSSRV_STATID_CACHE: { PDNSSRV_CACHE_STATS pstat = ( PDNSSRV_CACHE_STATS ) pStat; dwStat( L"Checks where cache exceeded limit", pstat->CacheExceededLimitChecks ); dwStat( L"Successful cache enforcement passes", pstat->SuccessfulFreePasses ); dwStat( L"Failed cache enforcement passes", pstat->FailedFreePasses ); dwStat( L"Passes requiring aggressive free", pstat->PassesRequiringAggressiveFree ); dwStat( L"Passes where nothing was freed", pstat->PassesWithNoFrees ); break; } default: break; } // // Cleanup and return. // return sc; } SCODE CDnsWrap::dnsGetStatistics( IWbemClassObject * pClass, IWbemObjectSink * pHandler, DWORD dwStatId ) /*++ Routine Description: Retrieve DNS statistics. Arguments: dwStatId -- statistic ID or zero for all pClass -- ptr to StatisticsCollection class object Return Value: None --*/ { SCODE sc = S_OK; DNS_STATUS status = ERROR_SUCCESS; PDNS_RPC_BUFFER pstatbuff = NULL; BSTR bstrStatClass = NULL; IWbemClassObject * pStatClass = NULL; // // Retrieve RPC stat buffer from server. // if ( dwStatId == 0 ) { dwStatId = DNSSRV_STATID_ALL; } status = DnssrvGetStatistics( PVD_DNS_LOCAL_SERVER, dwStatId, &pstatbuff ); if ( status != ERROR_SUCCESS ) { ThrowException( status ); } if ( !pstatbuff ) { ThrowException( ERROR_NO_DATA ); } // // Iterate stats in buffer. Add each "single stat" in the buffer // to the WMI instance as a StatisticCollection. Add each individual // statistics in each "single stat" buffer as a value to that // statistic collection. // PDNSSRV_STAT pstat; PBYTE pch = &pstatbuff->Buffer[ 0 ]; PBYTE pchstop = pch + pstatbuff->dwLength; while ( sc == S_OK && pch < pchstop ) { pstat = ( PDNSSRV_STAT ) pch; pch = ( PBYTE ) GET_NEXT_STAT_IN_BUFFER( pstat ); sc = dnsWrapHandleSingleStat( pClass, pHandler, pstat ); if ( sc != S_OK ) { break; } } // // Cleanup and return. // SysFreeString( bstrStatClass ); if ( pstatbuff ) { MIDL_user_free( pstatbuff ); } if ( pStatClass ) { pStatClass->Release(); } return sc; } // CDnsWrap::dnsGetStatistics