|
|
/*++
Copyright (c) 2000 Microsoft corporation
Module Name:
select.c
Abstract:
Implements the partial selection of configuration from the full MM configuration data structures.
--*/
#include <precomp.h>
typedef struct _SELECT_CTXT { ULONG *Subnets; ULONG nSubnets; } SELECT_CTXT, *PSELECT_CTXT;
DWORD DeleteScopesCallback( IN OUT PMM_ITERATE_CTXT Ctxt ) { PSELECT_CTXT SelectCtxt = Ctxt->ExtraCtxt; ULONG *Subnets, nSubnets, i; Subnets = SelectCtxt->Subnets; nSubnets = SelectCtxt->nSubnets;
for( i = 0; i < nSubnets; i ++ ) { if( Subnets[i] == Ctxt->Scope->Address ) break; }
if( i == nSubnets ) { //
// Returning KEY_DELETED will cause the IterateScopes
// routine to delete this scope out.
//
return ERROR_KEY_DELETED; } return NO_ERROR; }
DWORD OptionCheckForClass( IN OUT PMM_ITERATE_CTXT Ctxt ) { PM_CLASSDEF ClassDef = Ctxt->ExtraCtxt;
//
// If the class specified in ExtraCtxt matches the current
// option's user or vendor class, then bummer -- fail
// immediately with error code ERROR_DEVICE_IN_USE to
// indicate that this class is needed and can't be deleted
//
if( Ctxt->UserClass == ClassDef || Ctxt->VendorClass == ClassDef ) { return ERROR_DEVICE_IN_USE; }
return NO_ERROR; }
DWORD OptionCheckForOptDef( IN OUT PMM_ITERATE_CTXT Ctxt ) { PMM_ITERATE_CTXT OtherCtxt = Ctxt->ExtraCtxt;
//
// If the current option matches the optdef parameters, then
// we need to save the optdef ..
//
if( Ctxt->VendorClass == OtherCtxt->VendorClass && Ctxt->Option->OptId == OtherCtxt->OptDef->OptId ) { return ERROR_DEVICE_IN_USE; }
return NO_ERROR; }
DWORD ScopeReservationsCheckForClass( IN OUT PMM_ITERATE_CTXT Ctxt ) { return IterateReservationOptions( Ctxt->Server, Ctxt->Res, Ctxt->ExtraCtxt, OptionCheckForClass ); }
DWORD ScopeReservationsCheckForOptDef( IN OUT PMM_ITERATE_CTXT Ctxt ) { return IterateReservationOptions( Ctxt->Server, Ctxt->Res, Ctxt->ExtraCtxt, OptionCheckForOptDef ); }
DWORD ScopeCheckForClass( IN OUT PMM_ITERATE_CTXT Ctxt ) { DWORD Error; //
// Iterate over each option in the current scope to see if
// any of them use the same class
//
Error = IterateScopeOptions( Ctxt->Scope, Ctxt->ExtraCtxt, OptionCheckForClass ); if( NO_ERROR != Error ) return Error;
//
// Otherwise iterate for each reservation to see if this is a
// problem.
//
return IterateScopeReservations( Ctxt->Scope, Ctxt->ExtraCtxt, ScopeReservationsCheckForClass ); }
DWORD ScopeCheckForOptDef( IN OUT PMM_ITERATE_CTXT Ctxt ) { DWORD Error; //
// Iterate over each option in the current scope to see if
// any of them use the same class
//
Error = IterateScopeOptions( Ctxt->Scope, Ctxt->ExtraCtxt, OptionCheckForOptDef ); if( NO_ERROR != Error ) return Error;
//
// Otherwise iterate for each reservation to see if this is a
// problem.
//
return IterateScopeReservations( Ctxt->Scope, Ctxt->ExtraCtxt, ScopeReservationsCheckForOptDef ); }
DWORD DeleteClassesCallback( IN OUT PMM_ITERATE_CTXT Ctxt ) { DWORD Error; //
// Go through each subnet to see if there is any option
// configured to use this class
//
Error = IterateScopes( Ctxt->Server, Ctxt->ClassDef, ScopeCheckForClass );
//
// If the specified class is in use, then don't
// delete. Otherwise delete.
//
if( ERROR_DEVICE_IN_USE == Error ) return NO_ERROR; if (NO_ERROR == Error ) return ERROR_KEY_DELETED; return Error; }
DWORD DeleteOptDefsCallback( IN OUT PMM_ITERATE_CTXT Ctxt ) { DWORD Error; //
// Go through each subnet to see if there is any option
// configured to use this optdef
//
Error = IterateScopes( Ctxt->Server, Ctxt, ScopeCheckForOptDef );
//
// If the specified class is in use, then don't
// delete. Otherwise delete.
//
if( ERROR_DEVICE_IN_USE == Error ) return NO_ERROR; if (NO_ERROR == Error ) return ERROR_KEY_DELETED; return Error; }
DWORD SelectConfiguration( IN OUT PM_SERVER Server, IN ULONG *Subnets, IN ULONG nSubnets ) { SELECT_CTXT Ctxt = { Subnets, nSubnets }; DWORD Error; ULONG i; WCHAR SubnetAddress[30]; //
// No selection needed if nSubnets == 0, as this indicates
// that the whole configuration is to be used
//
Tr("SelectConfiguration entered\n"); if( nSubnets == 0 ) return NO_ERROR;
//
// First go through all scopes and check if all the required
// scopes are present
//
for( i = 0; i < nSubnets ; i ++ ) { PM_SUBNET Subnet; Error = MemServerGetUAddressInfo( Server, Subnets[i], &Subnet, NULL, NULL, NULL ); if( NO_ERROR != Error ) { Tr("Cant find subnet 0x%lx: %ld\n", Subnets[i], Error ); if( ERROR_FILE_NOT_FOUND == Error ) { IpAddressToStringW(Subnets[i], (LPWSTR)SubnetAddress); DhcpEximErrorSubnetNotFound( (LPWSTR)SubnetAddress ); Error = ERROR_CAN_NOT_COMPLETE; } return Error; } } //
// Global options are never needed.. so we can delete them.
//
MemOptClassFree( &Server->Options ); //
// Go through all the subnets and delete ones that are
// not selected
//
Error = IterateScopes( Server, &Ctxt, DeleteScopesCallback );
if( NO_ERROR != Error ) { Tr("IterateScopes: %ld\n", Error ); return Error; }
//
// Now check if all the option-defs are needed
//
Error = IterateOptDefs( Server, NULL, DeleteOptDefsCallback );
if( NO_ERROR != Error ) { Tr("IterateOptDefs: %ld\n", Error ); return Error; }
//
// Now check if all the user classes are needed
//
Error = IterateClasses( Server, NULL, DeleteClassesCallback );
if( NO_ERROR != Error ) { Tr("IterateClasses: %ld\n", Error ); return Error; }
return NO_ERROR; }
|