|
|
/********************************************************************/ /** Copyright(c) 1985-1997 Microsoft Corporation. **/ /********************************************************************/
//***
//
// Filename: rtridobj
//
// Description: Support routines to manipulate router information in the
// router object
//
// History: Feb 11,1998 NarenG Created original version.
//
#include "dimsvcp.h"
#include <activeds.h>
#include <adsi.h>
#include <ntdsapi.h>
#include <dsgetdc.h>
#include <lmapibuf.h>
#define SECURITY_WIN32
#include <security.h>
#include <routprot.h>
#include <rtinfo.h>
#include <dimsvc.h> // Generated by MIDL
#define ROUTER_IDENTITY_OBJECT_NAME TEXT("CN=RouterIdentity")
#define ROUTER_OBJECT_ATTRIBUTE_NAME TEXT("MsRRASAttribute")
#define ROUTER_LDAP_PREFIX TEXT("LDAP://")
#define ROUTER_CN_COMMA TEXT(",")
#define ROUTER_IDENTITY_CLASS TEXT("RRASAdministrationConnectionPoint")
LPWSTR RouterObjectAttributeNames[] = { ROUTER_OBJECT_ATTRIBUTE_NAME };
//**
//
// Call: RouterIdentityObjectOpen
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Given the machine name of the router, will return the handle
// to the router's administration service point or router object.
//
DWORD RouterIdentityObjectOpen( IN LPWSTR lpwszRouterName, IN DWORD dwRouterType, OUT HANDLE * phObjectRouterIdentity ) { DWORD dwRetCode; LPWSTR lpwszRouterIdentityObjectPath = NULL; LPWSTR lpwszComputerObjectPath = NULL; DOMAIN_CONTROLLER_INFO * pDomainControllerInfo = NULL; HRESULT hResult = HRESULT_FROM_WIN32(NO_ERROR); DWORD dwCharCount;
do { dwRetCode = DsGetDcName( NULL, NULL, NULL, NULL, DS_DIRECTORY_SERVICE_REQUIRED | DS_WRITABLE_REQUIRED, &pDomainControllerInfo );
if ( dwRetCode != NO_ERROR ) { TracePrintfExA( gblDIMConfigInfo.dwTraceId, TRACE_DIM, "No DS located, DsGetDcName()=%d", dwRetCode ); break; }
if ( !( pDomainControllerInfo->Flags & DS_DS_FLAG ) ) { TracePrintfExA( gblDIMConfigInfo.dwTraceId, TRACE_DIM, "No DS located");
dwRetCode = ERROR_DOMAIN_CONTROLLER_NOT_FOUND;
break; }
//
// Get the CN of the router object
//
dwCharCount = 200;
lpwszComputerObjectPath = LOCAL_ALLOC(LPTR, dwCharCount*sizeof(WCHAR)); if (lpwszComputerObjectPath == NULL) { TracePrintfExA( gblDIMConfigInfo.dwTraceId, TRACE_DIM, "Memory exhausted -- unable to continue");
dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
break; }
if ( !GetComputerObjectName( NameFullyQualifiedDN, lpwszComputerObjectPath, &dwCharCount ) ) { //
// We failed for some other reason
//
LPWSTR lpwsComputerObjectPathReAlloc = LOCAL_REALLOC( lpwszComputerObjectPath, (++dwCharCount)*sizeof(WCHAR) );
if ( lpwsComputerObjectPathReAlloc == NULL ) { dwRetCode = ERROR_NOT_ENOUGH_MEMORY;
break; }
lpwszComputerObjectPath = lpwsComputerObjectPathReAlloc;
if ( !GetComputerObjectName( NameFullyQualifiedDN, lpwszComputerObjectPath, &dwCharCount ) ) { dwRetCode = GetLastError();
break; } }
lpwszRouterIdentityObjectPath = LOCAL_ALLOC( LPTR, sizeof( ROUTER_LDAP_PREFIX ) + sizeof( ROUTER_IDENTITY_OBJECT_NAME ) + sizeof( ROUTER_CN_COMMA ) + ((wcslen( lpwszComputerObjectPath )+1)* sizeof(WCHAR)));
if ( lpwszRouterIdentityObjectPath == NULL ) { dwRetCode = ERROR_NOT_ENOUGH_MEMORY; break; }
wcscpy( lpwszRouterIdentityObjectPath, ROUTER_LDAP_PREFIX ); wcscat( lpwszRouterIdentityObjectPath, ROUTER_IDENTITY_OBJECT_NAME ); wcscat( lpwszRouterIdentityObjectPath, ROUTER_CN_COMMA ); wcscat( lpwszRouterIdentityObjectPath, lpwszComputerObjectPath );
//
// Try to open the router identity object
//
hResult = ADSIOpenDSObject( lpwszRouterIdentityObjectPath, NULL, NULL, 0, phObjectRouterIdentity );
if ( hResult == HRESULT_FROM_WIN32( ERROR_DS_NO_SUCH_OBJECT ) ) { HANDLE hObjectComputer; ADS_ATTR_INFO AttributeEntries[2]; ADSVALUE ObjectClassAttributeValue; ADSVALUE msRRASAttributeValues[3]; WCHAR wchmsRRASAttributeValue1[50]; WCHAR wchmsRRASAttributeValue2[50]; WCHAR wchmsRRASAttributeValue3[50]; DWORD dwIndex = 0;
//
// If we failed because it doesn't exist, then create it
//
wcscpy( lpwszRouterIdentityObjectPath, ROUTER_LDAP_PREFIX ); wcscat( lpwszRouterIdentityObjectPath, lpwszComputerObjectPath );
hResult = ADSIOpenDSObject( lpwszRouterIdentityObjectPath, NULL, NULL, 0, &hObjectComputer );
if ( FAILED( hResult ) ) { dwRetCode = HRESULT_CODE( hResult );
break; }
//
// Set up attributes for this object
//
ObjectClassAttributeValue.dwType = ADSTYPE_CASE_IGNORE_STRING; ObjectClassAttributeValue.CaseIgnoreString = ROUTER_IDENTITY_CLASS;
AttributeEntries[0].pszAttrName = TEXT("ObjectClass"); AttributeEntries[0].dwControlCode = ADS_ATTR_APPEND; AttributeEntries[0].dwADsType = ADSTYPE_CASE_IGNORE_STRING; AttributeEntries[0].pADsValues = &ObjectClassAttributeValue; AttributeEntries[0].dwNumValues = 1;
if ( dwRouterType & ROUTER_ROLE_RAS ) { wsprintf( wchmsRRASAttributeValue1, TEXT("%d:%d:%d"), DIM_MS_VENDOR_ID, 6, 602 );
msRRASAttributeValues[dwIndex].dwType = ADSTYPE_CASE_IGNORE_STRING; msRRASAttributeValues[dwIndex].CaseIgnoreString = wchmsRRASAttributeValue1; dwIndex++; }
if ( dwRouterType & ROUTER_ROLE_LAN ) { wsprintf( wchmsRRASAttributeValue2, TEXT("%d:%d:%d"), DIM_MS_VENDOR_ID, 6, 601 );
msRRASAttributeValues[dwIndex].dwType = ADSTYPE_CASE_IGNORE_STRING; msRRASAttributeValues[dwIndex].CaseIgnoreString = wchmsRRASAttributeValue2; dwIndex++; }
if ( dwRouterType & ROUTER_ROLE_WAN ) { wsprintf( wchmsRRASAttributeValue3, TEXT("%d:%d:%d"), DIM_MS_VENDOR_ID, 6, 603 );
msRRASAttributeValues[dwIndex].dwType = ADSTYPE_CASE_IGNORE_STRING; msRRASAttributeValues[dwIndex].CaseIgnoreString = wchmsRRASAttributeValue3;
dwIndex++; }
AttributeEntries[1].pszAttrName = ROUTER_OBJECT_ATTRIBUTE_NAME; AttributeEntries[1].dwControlCode = ADS_ATTR_APPEND; AttributeEntries[1].dwADsType = ADSTYPE_CASE_IGNORE_STRING; AttributeEntries[1].pADsValues = msRRASAttributeValues; AttributeEntries[1].dwNumValues = dwIndex;
hResult = ADSICreateDSObject( hObjectComputer, ROUTER_IDENTITY_OBJECT_NAME, AttributeEntries, 2 );
ADSICloseDSObject( hObjectComputer );
if ( FAILED( hResult ) ) { dwRetCode = HRESULT_CODE( hResult );
break; }
wcscpy(lpwszRouterIdentityObjectPath, ROUTER_LDAP_PREFIX); wcscat(lpwszRouterIdentityObjectPath, ROUTER_IDENTITY_OBJECT_NAME); wcscat(lpwszRouterIdentityObjectPath, ROUTER_CN_COMMA ); wcscat(lpwszRouterIdentityObjectPath, lpwszComputerObjectPath);
//
// Now open it to get the handle
//
hResult = ADSIOpenDSObject( lpwszRouterIdentityObjectPath, NULL, NULL, 0, phObjectRouterIdentity ); }
if ( FAILED( hResult ) ) { dwRetCode = HRESULT_CODE( hResult ); } else { dwRetCode = NO_ERROR; }
} while( FALSE );
if ( lpwszRouterIdentityObjectPath != NULL ) { LOCAL_FREE( lpwszRouterIdentityObjectPath ); }
if ( lpwszComputerObjectPath != NULL ) { LOCAL_FREE( lpwszComputerObjectPath ); }
if ( pDomainControllerInfo != NULL ) { NetApiBufferFree( pDomainControllerInfo ); }
TracePrintfExA( gblDIMConfigInfo.dwTraceId, TRACE_DIM, "RouterIdentityObjectOpen returned %d", dwRetCode );
return( dwRetCode ); }
//**
//
// Call: RouterIdentityObjectClose
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will close the router object.
//
VOID RouterIdentityObjectClose( IN HANDLE hObjectRouterIdentity ) { ADSICloseDSObject( hObjectRouterIdentity ); }
//**
//
// Call: RouterIdentityObjectGetAttributes
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will retreive all the attributes of the give Router object
//
DWORD RouterIdentityObjectGetAttributes( IN HANDLE hRouterIdentityObject, OUT HANDLE * phRouterIdentityAttributes
) { ADS_ATTR_INFO * pADSAttributes = NULL; DWORD dwNumAttributesReturned = 0; HRESULT hResult;
*phRouterIdentityAttributes = NULL;
//
// Get all the attributes in this object
//
hResult = ADSIGetObjectAttributes( hRouterIdentityObject, RouterObjectAttributeNames, sizeof( RouterObjectAttributeNames ) / sizeof( LPWSTR ), &pADSAttributes, &dwNumAttributesReturned );
if ( FAILED( hResult ) ) { return( HRESULT_CODE( hResult ) ); }
if ( dwNumAttributesReturned > 0 ) { *phRouterIdentityAttributes = (HANDLE)pADSAttributes; } else { TracePrintfExA( gblDIMConfigInfo.dwTraceId, TRACE_DIM, "No attributes in identity object" ); }
return( NO_ERROR ); }
//**
//
// Call: RouterIdentityObjectIsValueSet
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will check to see if a give value exists for the attribute
//
BOOL RouterIdentityObjectIsValueSet( IN HANDLE hRouterIdentityAttributes, IN DWORD dwVendorId, IN DWORD dwType, IN DWORD dwValue ) { ADS_ATTR_INFO * pADSAttributes = (ADS_ATTR_INFO *)hRouterIdentityAttributes; DWORD dwIndex; WCHAR wchValue[100]; CHAR chValue[100];
if ( pADSAttributes == NULL ) { return( FALSE ); }
if (_wcsicmp(pADSAttributes->pszAttrName, ROUTER_OBJECT_ATTRIBUTE_NAME)!=0) { return( FALSE ); }
wsprintf( wchValue, TEXT("%d:%d:%d"), dwVendorId, dwType, dwValue ); sprintf( chValue, "%d:%d:%d", dwVendorId, dwType, dwValue ); for( dwIndex = 0; dwIndex < pADSAttributes->dwNumValues; dwIndex ++ ) { ADSVALUE * pADsValue = &(pADSAttributes->pADsValues[dwIndex]);
switch (pADsValue->dwType) {
case ADSTYPE_PROV_SPECIFIC: { ADS_PROV_SPECIFIC *pProviderSpecific; pProviderSpecific = &pADsValue->ProviderSpecific; if (strncmp( pProviderSpecific->lpValue, chValue, pProviderSpecific->dwLength) == 0 ) { return( TRUE ); } break; } case ADSTYPE_CASE_IGNORE_STRING: if ( _wcsicmp( pADsValue->CaseIgnoreString, wchValue ) == 0 ) { return( TRUE ); } break;
default : //same as ADSTYPE_CASE_IGNORE_STRING
if ( _wcsicmp( pADsValue->CaseIgnoreString, wchValue ) == 0 ) { return( TRUE ); } break; } }
return( FALSE ); }
//**
//
// Call: RouterIdentityObjectGetValue
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will get the specified indexed value from the router object
//
DWORD RouterIdentityObjectGetValue( IN HANDLE hRouterIdentityAttributes, IN DWORD dwValueIndex, IN DWORD * lpdwVendorId, IN DWORD * lpdwType, IN DWORD * lpdwValue ) { ADS_ATTR_INFO * pADSAttributes = (ADS_ATTR_INFO *)hRouterIdentityAttributes; DWORD dwIndex; ADSVALUE * pADsValue;
if ( pADSAttributes == NULL ) { return( ERROR_DS_NO_ATTRIBUTE_OR_VALUE ); }
if (_wcsicmp(pADSAttributes->pszAttrName, ROUTER_OBJECT_ATTRIBUTE_NAME)!=0) { return( ERROR_DS_NO_ATTRIBUTE_OR_VALUE ); }
if ( dwValueIndex >= pADSAttributes->dwNumValues ) { *lpdwVendorId = (DWORD)-1; *lpdwType = (DWORD)-1; *lpdwValue = (DWORD)-1;
return( NO_ERROR ); }
pADsValue = &(pADSAttributes->pADsValues[dwValueIndex]);
switch (pADsValue->dwType) {
case ADSTYPE_PROV_SPECIFIC: { ADS_PROV_SPECIFIC *pProviderSpecific; CHAR chValue[100]; pProviderSpecific = &pADsValue->ProviderSpecific;
strncpy(chValue, pProviderSpecific->lpValue, pProviderSpecific->dwLength); chValue[pProviderSpecific->dwLength] = 0; if (scanf( chValue, TEXT("%d:%d:%d"), lpdwVendorId, lpdwType, lpdwValue ) == EOF) { return ERROR_DS_INVALID_ATTRIBUTE_SYNTAX; } break; } default : { if (swscanf( pADsValue->CaseIgnoreString, TEXT("%d:%d:%d"), lpdwVendorId, lpdwType, lpdwValue ) == EOF) { return ERROR_DS_INVALID_ATTRIBUTE_SYNTAX; } break; } } return( NO_ERROR ); }
//**
//
// Call: RouterIdentityObjectAddRemoveValue
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will add or remove a value from the multi-valued attribute
//
DWORD RouterIdentityObjectAddRemoveValue( IN HANDLE hRouterIdentityObject, IN DWORD dwVendorId, IN DWORD dwType, IN DWORD dwValue, IN BOOL fAdd ) { HRESULT hResult; DWORD dwNumAttributesModified; ADS_ATTR_INFO AttributeEntry[1]; WCHAR wchValue[100]; ADSVALUE AttributeValue;
wsprintf( wchValue, TEXT("%d:%d:%d"), dwVendorId, dwType, dwValue );
AttributeValue.dwType = ADSTYPE_CASE_IGNORE_STRING; AttributeValue.CaseIgnoreString = wchValue;
AttributeEntry[0].pszAttrName = ROUTER_OBJECT_ATTRIBUTE_NAME; AttributeEntry[0].dwControlCode = ( fAdd ) ? ADS_ATTR_APPEND : ADS_ATTR_DELETE; AttributeEntry[0].dwADsType = ADSTYPE_CASE_IGNORE_STRING; AttributeEntry[0].pADsValues = &AttributeValue; AttributeEntry[0].dwNumValues = 1;
if ( fAdd ) { TracePrintfExA( gblDIMConfigInfo.dwTraceId, TRACE_DIM, "Adding value %ws in the Router Identity Object", wchValue ); } else { TracePrintfExA( gblDIMConfigInfo.dwTraceId, TRACE_DIM, "Removing value %ws in the Router Identity Object", wchValue ); }
hResult = ADSISetObjectAttributes( hRouterIdentityObject, AttributeEntry, 1, &dwNumAttributesModified ); if ( FAILED( hResult ) ) { return( HRESULT_CODE( hResult ) ); }
return( NO_ERROR ); }
//**
//
// Call: RouterIdentityObjectFreeAttributes
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Frees allocated set of attributes returned by
// RouterIdentityObjectGetAttributes
//
VOID RouterIdentityObjectFreeAttributes( IN HANDLE hRouterIdentityAttributes ) { if ( hRouterIdentityAttributes != NULL ) { FreeADsMem( (ADS_ATTR_INFO *)hRouterIdentityAttributes ); } }
//**
//
// Call: RouterIdentityObjectSetAttributes
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will gather all current configuration information and plumb it
// into the router identity object in the DS.
//
// Note:
// This API first takes the lock on the interface table,
// then it takes the lock around the device table to get the
// installed device types. Hence this API MUST NOT be called
// while holding a lock around the interface table since this
// violates the design principal of first holding the
// device lock before holding the interface lock.
//
DWORD RouterIdentityObjectSetAttributes( IN HANDLE hRouterIdentityObject ) { DWORD dwRetCode; HANDLE hRouterIdentityAttributes; DWORD dwIndex = 0; ROUTER_IDENTITY_ATTRIBUTE RIAttributes[DIM_MAX_IDENTITY_ATTRS]; DWORD dwXportIndex;
//
// Obtain router identity information plumbed in the DS currently
//
dwRetCode = RouterIdentityObjectGetAttributes( hRouterIdentityObject, &hRouterIdentityAttributes );
if ( dwRetCode != NO_ERROR ) { return( dwRetCode ); }
//
// Now get the current running configuration of the router
//
//
// First, what is our role?
//
if ( gblDIMConfigInfo.dwRouterRole & ROUTER_ROLE_LAN ) { RIAttributes[dwIndex].dwVendorId = DIM_MS_VENDOR_ID; RIAttributes[dwIndex].dwType = 6; RIAttributes[dwIndex].dwValue = 601;
dwIndex++; }
if ( gblDIMConfigInfo.dwRouterRole & ROUTER_ROLE_RAS ) { RIAttributes[dwIndex].dwVendorId = DIM_MS_VENDOR_ID; RIAttributes[dwIndex].dwType = 6; RIAttributes[dwIndex].dwValue = 602;
dwIndex++; }
if ( gblDIMConfigInfo.dwRouterRole & ROUTER_ROLE_WAN ) { RIAttributes[dwIndex].dwVendorId = DIM_MS_VENDOR_ID; RIAttributes[dwIndex].dwType = 6; RIAttributes[dwIndex].dwValue = 603;
dwIndex++; }
//
// Check if a LAN interface exists
//
EnterCriticalSection( &(gblInterfaceTable.CriticalSection) );
if ( IfObjectDoesLanInterfaceExist() ) { RIAttributes[dwIndex].dwVendorId = 311; RIAttributes[dwIndex].dwType = 6; RIAttributes[dwIndex].dwValue = 712;
dwIndex++; }
//
// Get all IP routing protocols
//
if ( ( dwXportIndex = GetTransportIndex( PID_IP ) ) != (DWORD)-1 ) { BYTE * pGlobalInfo = NULL; DWORD dwGlobalInfoSize = 0;
dwRetCode = gblRouterManagers[dwXportIndex].DdmRouterIf.GetGlobalInfo( pGlobalInfo, &dwGlobalInfoSize );
if ( dwRetCode == ERROR_INSUFFICIENT_BUFFER ) { if ( dwGlobalInfoSize > 0 ) { pGlobalInfo = LOCAL_ALLOC( LPTR, dwGlobalInfoSize );
if ( pGlobalInfo != NULL ) { dwRetCode = gblRouterManagers[dwXportIndex].DdmRouterIf.GetGlobalInfo( pGlobalInfo, &dwGlobalInfoSize );
if ( dwRetCode == NO_ERROR ) { DWORD dwRoutingProtIndex; RTR_INFO_BLOCK_HEADER * pInfoBlock = (RTR_INFO_BLOCK_HEADER *)(pGlobalInfo);
for ( dwRoutingProtIndex = 0; dwRoutingProtIndex < pInfoBlock->TocEntriesCount; dwRoutingProtIndex++ ) { DWORD dwVendorId;
RIAttributes[dwIndex].dwType = TYPE_FROM_PROTO_ID( pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
//
// Add unicast and multicast protocol ids
//
if ( ( RIAttributes[dwIndex].dwType == PROTO_TYPE_UCAST ) || ( RIAttributes[dwIndex].dwType == PROTO_TYPE_MCAST ) ) { DWORD dwProtoId; dwVendorId = VENDOR_FROM_PROTO_ID(
pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
dwProtoId = PROTO_FROM_PROTO_ID(
pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
//
// Nothing defined for dhcp relay agent
//
if ( dwProtoId == PROTO_IP_BOOTP ) { continue; } if ( ( dwVendorId == PROTO_VENDOR_MS0 ) || ( dwVendorId == PROTO_VENDOR_MS1 ) || ( dwVendorId == PROTO_VENDOR_MS2 ) ) { RIAttributes[dwIndex].dwVendorId = 311; } else { RIAttributes[dwIndex].dwVendorId = dwVendorId; }
RIAttributes[dwIndex].dwValue = PROTO_FROM_PROTO_ID( pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
dwIndex++; }
//
// Add ms0 protocols
//
else if (RIAttributes[dwIndex].dwType == PROTO_TYPE_MS0 ) { DWORD dwProtoId; dwVendorId = VENDOR_FROM_PROTO_ID(
pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
dwProtoId = PROTO_FROM_PROTO_ID(
pInfoBlock->TocEntry[dwRoutingProtIndex].InfoType );
//
// Check for NAT
// Vendor= MS, TypeMajor= 6, TypeMinor= 604
//
if ( ( dwVendorId == PROTO_VENDOR_MS1 ) && ( dwProtoId == PROTO_IP_NAT) ) { RIAttributes[dwIndex].dwVendorId = PROTO_VENDOR_MS1; RIAttributes[dwIndex].dwType = 6; RIAttributes[dwIndex].dwValue = 604; dwIndex++; } } } }
LOCAL_FREE( pGlobalInfo ); } } }
// As per amritanr, if you have the ip router installed,
// then ip forwarding is always turned on.
//
// Ip Fwd'ing Enabled: Vendor= MS, TypeMajor= 6, TypeMinor= 501
//
RIAttributes[dwIndex].dwVendorId = PROTO_VENDOR_MS1; RIAttributes[dwIndex].dwType = 6; RIAttributes[dwIndex].dwValue = 501; dwIndex++; }
//
// Get all IPX routing protocols
//
if ( ( dwXportIndex = GetTransportIndex( PID_IPX ) ) != (DWORD)-1 ) { // All nt5 ipx routers support rip and sap. Go ahead
// and attributes for both.
//
// IPXRIP: Vendor= MS, TypeMajor= 5, TypeMinor= 1
//
RIAttributes[dwIndex].dwVendorId = PROTO_VENDOR_MS1; RIAttributes[dwIndex].dwType = 5; RIAttributes[dwIndex].dwValue = 1; dwIndex++;
// IPXSAP: Vendor= MS, TypeMajor= 5, TypeMinor= 2
//
RIAttributes[dwIndex].dwVendorId = PROTO_VENDOR_MS1; RIAttributes[dwIndex].dwType = 5; RIAttributes[dwIndex].dwValue = 2; dwIndex++;
// Ipx Fwd'ing Enabled: Vendor= MS, TypeMajor= 6, TypeMinor= 502
//
RIAttributes[dwIndex].dwVendorId = PROTO_VENDOR_MS1; RIAttributes[dwIndex].dwType = 6; RIAttributes[dwIndex].dwValue = 502; dwIndex++; }
LeaveCriticalSection( &(gblInterfaceTable.CriticalSection) );
RIAttributes[dwIndex].dwVendorId = (DWORD)-1; RIAttributes[dwIndex].dwType = (DWORD)-1; RIAttributes[dwIndex].dwValue = (DWORD)-1;
//
// Get all the RAS server information
//
if ( gblDIMConfigInfo.dwRouterRole & ( ROUTER_ROLE_RAS | ROUTER_ROLE_WAN ) ) { DWORD (*DDMGetIdentityAttributes)( ROUTER_IDENTITY_ATTRIBUTE * ) = (DWORD(*)( ROUTER_IDENTITY_ATTRIBUTE * )) GetDDMEntryPoint("DDMGetIdentityAttributes");
if(NULL != DDMGetIdentityAttributes) { dwRetCode = DDMGetIdentityAttributes( RIAttributes ); } else { ASSERT(FALSE); } }
//
// Now obtain walk thru the current configration an make sure that
// all of it is plumbed. If it is not then go ahead and set it.
//
for ( dwIndex = 0; RIAttributes[dwIndex].dwVendorId != (DWORD)-1; dwIndex++ ) { //
// If this attribute is not set, then set it
//
if ( !RouterIdentityObjectIsValueSet( hRouterIdentityAttributes, RIAttributes[dwIndex].dwVendorId, RIAttributes[dwIndex].dwType, RIAttributes[dwIndex].dwValue ) ) { RouterIdentityObjectAddRemoveValue( hRouterIdentityObject, RIAttributes[dwIndex].dwVendorId, RIAttributes[dwIndex].dwType, RIAttributes[dwIndex].dwValue, TRUE ); } }
//
// Now walk thru and remove attributes in the DS that are not in our
// current configuration. We reconcile all attributes with
// dwType values 0,1 or 5, and with dwVendorId of 311 (Microsoft) with
// dwType value of 6.
//
for ( dwIndex = 0;; dwIndex++ ) { DWORD dwVendorId; DWORD dwType; DWORD dwValue; DWORD dwCurrentValueIndex; BOOL fInCurrentConfiguration = FALSE;
dwRetCode = RouterIdentityObjectGetValue( hRouterIdentityAttributes, dwIndex, &dwVendorId, &dwType, &dwValue );
if ( dwRetCode != NO_ERROR ) { break; }
//
// We are done
//
if ( dwVendorId == (DWORD)-1 ) { break; }
//
// Ignore these types
//
if ( ( dwType != 0 ) && ( dwType != 1 ) && ( dwType != 5 ) && ( !( ( dwType == 6 ) && ( dwVendorId == DIM_MS_VENDOR_ID ) ) ) ) { continue; }
//
// Now check to see it this attribute is a member of our current
// configuration
//
for ( dwCurrentValueIndex = 0; RIAttributes[dwCurrentValueIndex].dwVendorId != (DWORD)-1; dwCurrentValueIndex++ ) { if ( (RIAttributes[dwCurrentValueIndex].dwVendorId == dwVendorId)&& (RIAttributes[dwCurrentValueIndex].dwType == dwType ) && (RIAttributes[dwCurrentValueIndex].dwValue == dwValue ) ) { //
// Attribute is part of current configuration
//
fInCurrentConfiguration = TRUE; } }
if ( !fInCurrentConfiguration ) { //
// Remove this attribute from the DS since it is not in our
// current configuration
//
dwRetCode = RouterIdentityObjectAddRemoveValue( hRouterIdentityObject, dwVendorId, dwType, dwValue, FALSE ); if ( dwRetCode != NO_ERROR ) { break; } } }
RouterIdentityObjectFreeAttributes( hRouterIdentityAttributes );
return( dwRetCode ); }
//**
//
// Call: RouterIdentityObjectUpdateAttributes
//
// Returns: NO_ERROR - Success
// Non-zero returns - Failure
//
// Description: Will be called to update the attributes currently set in the DS
// or to set it if it was not able to be set originally
//
VOID RouterIdentityObjectUpdateAttributes( IN PVOID pParameter, IN BOOLEAN fTimedOut ) { DWORD dwRetCode = NO_ERROR; BOOL fCalledFromTimer = (BOOL)PtrToUlong(pParameter);
//
// Make sure service is in the running state
//
if ( gblDIMConfigInfo.ServiceStatus.dwCurrentState != SERVICE_RUNNING ) { if(fCalledFromTimer) { //
// Delete the timer if theres one queued before we
// return from here otherwise DeleteTimerQ in
// DimCleanup will hang.
//
RtlDeleteTimer(gblDIMConfigInfo.hTimerQ, gblDIMConfigInfo.hTimer, NULL); gblDIMConfigInfo.hTimer = NULL; } return; }
if ( fCalledFromTimer ) { //
// Always call DeleteTimer otherwise we will leak memory
//
RtlDeleteTimer( gblDIMConfigInfo.hTimerQ, gblDIMConfigInfo.hTimer, NULL );
gblDIMConfigInfo.hTimer = NULL;
//
// Called from timer thread so we first try to obtain a handle to
// the router idenitity object
//
dwRetCode = RouterIdentityObjectOpen( NULL, ( gblDIMConfigInfo.dwRouterRole ), &(gblDIMConfigInfo.hObjectRouterIdentity) );
if ( ( dwRetCode != NO_ERROR ) || ( gblDIMConfigInfo.hObjectRouterIdentity == NULL ) ) { //
// Check to see if service is stopping and create a timer for this
// only if it is in running state.
//
if(gblDIMConfigInfo.ServiceStatus.dwCurrentState == SERVICE_RUNNING) { //
// Couldn't access DC, try again later for a max of once a day
//
if ( gblDIMConfigInfo.dwRouterIdentityDueTime < 24*60*60*1000 ) { gblDIMConfigInfo.dwRouterIdentityDueTime *= 2; }
TracePrintfExA( gblDIMConfigInfo.dwTraceId, TRACE_DIM, "Could not access DC, will set router attributes later");
RtlCreateTimer( gblDIMConfigInfo.hTimerQ, &(gblDIMConfigInfo.hTimer), RouterIdentityObjectUpdateAttributes, (PVOID)TRUE, gblDIMConfigInfo.dwRouterIdentityDueTime, 0, WT_EXECUTEDEFAULT ); }
return; }
//
// Otherwise we succeeded in opening the router identity object
// and we set the identity information below.
//
} else { //
// If we do not have a handle for the router identity object, then
// either we are in the process of obtaining it or we are not
// a member of the DS, so in both cases simply return
//
if ( gblDIMConfigInfo.hObjectRouterIdentity == NULL ) { return; } }
//
// Can be called from different threads at the same time so we need
// Critical section around this code so that we do not have 2 writers to
// the DS at the same time that trample on each other. ex could be called
// by DDM thread as well as the timer thread.
//
EnterCriticalSection( &(gblDIMConfigInfo.CSRouterIdentity) );
TracePrintfExA( gblDIMConfigInfo.dwTraceId, TRACE_DIM, "Setting router attributes in the identity object" );
RouterIdentityObjectSetAttributes( gblDIMConfigInfo.hObjectRouterIdentity );
LeaveCriticalSection( &(gblDIMConfigInfo.CSRouterIdentity) ); }
//**
//
// Call: RouterIdentityObjectUpdateAttributesForDD
//
// Returns: None
//
// Description:
//
VOID RouterIdentityObjectUpdateAttributesForDDM( PVOID pParameter ) { RouterIdentityObjectUpdateAttributes( (PVOID)NULL, FALSE ); }
//**
//
// Call: RouterIdentityObjectUpdateDDMAttributes
//
// Returns: None
//
// Description: Export this call to DDM. When DDM calls this call, it already
// has taken a lock around it's device table and cannot make
// the call to update attributes directly because the
// RouterIdentityObjectUpdateAttributes call takes the
// lock around the RouterIdentity object leading to a deadlock.
// Hence we execute this call asynchronously using a worker
// thread.
//
//
VOID RouterIdentityObjectUpdateDDMAttributes( VOID ) { RtlQueueWorkItem( RouterIdentityObjectUpdateAttributesForDDM, NULL, WT_EXECUTEDEFAULT ); }
|