windows-nt/Source/XPSP1/NT/net/dhcp/server/exim/iterate.c

391 lines
9.6 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (C) 2000 Microsoft Corporation
Module Name:
iterate.c
Abstract:
This module contains routines that iterate over the MM data structures
--*/
#include <precomp.h>
DWORD
IterateClasses(
IN PM_SERVER Server,
IN PVOID ExtraCtxt,
IN DWORD (*Callback)( IN OUT PMM_ITERATE_CTXT )
)
{
ARRAY_LOCATION Loc;
DWORD Error;
MM_ITERATE_CTXT Ctxt;
PM_CLASSDEF ClassDef;
Ctxt.ExtraCtxt = ExtraCtxt;
Ctxt.Server = Server;
Error = MemArrayInitLoc( &Server->ClassDefs.ClassDefArray, &Loc );
while( NO_ERROR == Error ) {
Error = MemArrayGetElement(
&Server->ClassDefs.ClassDefArray, &Loc, &ClassDef );
ASSERT( NO_ERROR == Error );
Ctxt.ClassDef = ClassDef;
Error = Callback( &Ctxt );
if( ERROR_KEY_DELETED == Error ) {
//
// Delete this class ..
//
MemArrayDelElement(
&Server->ClassDefs.ClassDefArray, &Loc, &ClassDef );
MemClassDefFree( ClassDef );
Error = MemArrayAdjustLocation(
&Server->ClassDefs.ClassDefArray, &Loc );
} else {
if( NO_ERROR != Error ) return Error;
Error = MemArrayNextLoc(
&Server->ClassDefs.ClassDefArray, &Loc );
}
}
if( ERROR_FILE_NOT_FOUND == Error ) Error = NO_ERROR;
return Error;
}
PM_CLASSDEF
FindClass(
IN PM_SERVER Server,
IN ULONG ClassId
)
{
DWORD Error;
PM_CLASSDEF Class;
if( 0 == ClassId ) return NULL;
Error = MemServerGetClassDef(
Server, ClassId, NULL, 0, NULL, &Class );
ASSERT( NO_ERROR == Error );
if( NO_ERROR == Error ) return Class;
return NULL;
}
DWORD
IterateOptDefs(
IN PM_SERVER Server,
IN PVOID ExtraCtxt,
IN DWORD (*Callback)( IN OUT PMM_ITERATE_CTXT )
)
{
ARRAY_LOCATION Loc, Loc2;
DWORD Error;
MM_ITERATE_CTXT Ctxt;
PM_OPTDEF OptDef;
PM_OPTCLASSDEFL_ONE OptClassDefList;
Ctxt.ExtraCtxt = ExtraCtxt;
Ctxt.Server = Server;
Error = MemArrayInitLoc( &Server->OptDefs.Array, &Loc );
while( NO_ERROR == Error ) {
Error = MemArrayGetElement(
&Server->OptDefs.Array, &Loc, &OptClassDefList );
ASSERT( NO_ERROR == Error );
Ctxt.UserClass = FindClass( Server, OptClassDefList->ClassId );
Ctxt.VendorClass = FindClass( Server, OptClassDefList->VendorId );
Error = MemArrayInitLoc(
&OptClassDefList->OptDefList.OptDefArray, &Loc2 );
while( NO_ERROR == Error ) {
Error = MemArrayGetElement(
&OptClassDefList->OptDefList.OptDefArray, &Loc2,
&OptDef );
ASSERT( NO_ERROR == Error );
Ctxt.OptDef = OptDef;
Error = Callback( &Ctxt );
if( ERROR_KEY_DELETED == Error ) {
//
// Delete this optdef..
//
MemArrayDelElement(
&OptClassDefList->OptDefList.OptDefArray,
&Loc2, &OptDef );
MemOptDefFree( OptDef );
Error = MemArrayAdjustLocation(
&OptClassDefList->OptDefList.OptDefArray,
&Loc2 );
} else {
if( NO_ERROR != Error ) return Error;
Error = MemArrayNextLoc(
&OptClassDefList->OptDefList.OptDefArray, &Loc2 );
}
}
if( ERROR_FILE_NOT_FOUND != Error ) return Error;
Error = MemArrayNextLoc( &Server->OptDefs.Array, &Loc );
}
if( ERROR_FILE_NOT_FOUND == Error ) Error = NO_ERROR;
return Error;
}
DWORD
IterateOptionsOnOptClass(
IN PM_SERVER Server,
IN PM_OPTCLASS OptClass,
IN PVOID ExtraCtxt,
IN DWORD (*Callback)( IN OUT PMM_ITERATE_CTXT )
)
{
ARRAY_LOCATION Loc, Loc2;
DWORD Error;
MM_ITERATE_CTXT Ctxt;
PM_OPTION Option;
PM_ONECLASS_OPTLIST OptList;
Ctxt.ExtraCtxt = ExtraCtxt;
Ctxt.Server = Server;
Error = MemArrayInitLoc( &OptClass->Array, &Loc );
while( NO_ERROR == Error ) {
Error = MemArrayGetElement(
&OptClass->Array, &Loc, &OptList );
ASSERT( NO_ERROR == Error );
Ctxt.UserClass = FindClass( Server, OptList->ClassId );
Ctxt.VendorClass = FindClass( Server, OptList->VendorId );
Error = MemArrayInitLoc( &OptList->OptList, &Loc2 );
while( NO_ERROR == Error ) {
Error = MemArrayGetElement(
&OptList->OptList, &Loc2, &Option );
ASSERT( NO_ERROR == Error );
Ctxt.Option = Option;
Error = Callback( &Ctxt );
if( NO_ERROR != Error ) return Error;
Error = MemArrayNextLoc( &OptList->OptList, &Loc2 );
}
if( ERROR_FILE_NOT_FOUND != Error ) return Error;
Error = MemArrayNextLoc( &OptClass->Array, &Loc );
}
if( ERROR_FILE_NOT_FOUND == Error ) Error = NO_ERROR;
return Error;
}
DWORD
IterateServerOptions(
IN PM_SERVER Server,
IN PVOID ExtraCtxt,
IN DWORD (*Callback)( IN OUT PMM_ITERATE_CTXT )
)
{
return IterateOptionsOnOptClass(
Server, &Server->Options, ExtraCtxt, Callback );
}
DWORD
IterateScopeOptions(
IN PM_SUBNET Subnet,
IN PVOID ExtraCtxt,
IN DWORD (*Callback)( IN OUT PMM_ITERATE_CTXT )
)
{
return IterateOptionsOnOptClass(
(PM_SERVER)Subnet->ServerPtr,
&Subnet->Options, ExtraCtxt, Callback );
}
DWORD
IterateReservationOptions(
IN PM_SERVER Server,
IN PM_RESERVATION Res,
IN PVOID ExtraCtxt,
IN DWORD (*Callback)( IN OUT PMM_ITERATE_CTXT )
)
{
PM_SUBNET Subnet = NULL;
MemServerGetUAddressInfo(
Server, Res->Address, &Subnet, NULL, NULL, NULL );
return IterateOptionsOnOptClass(
Server, &Res->Options, ExtraCtxt, Callback );
}
PM_SSCOPE
FindSScope(
IN PM_SERVER Server,
IN DWORD SScopeId
)
{
DWORD Error;
PM_SSCOPE SScope;
if( SScopeId == INVALID_SSCOPE_ID ) return NULL;
Error = MemServerFindSScope(
Server, SScopeId, NULL, &SScope );
if( NO_ERROR != Error ) return NULL;
return SScope;
}
DWORD
IterateScopes(
IN PM_SERVER Server,
IN PVOID ExtraCtxt,
IN DWORD (*Callback)( IN OUT PMM_ITERATE_CTXT )
)
{
ARRAY_LOCATION Loc;
DWORD Error;
MM_ITERATE_CTXT Ctxt;
PM_SUBNET Scope;
Ctxt.ExtraCtxt = ExtraCtxt;
Ctxt.Server = Server;
Error = MemArrayInitLoc( &Server->Subnets, &Loc );
while( NO_ERROR == Error ) {
Error = MemArrayGetElement(
&Server->Subnets, &Loc, &Scope );
ASSERT( NO_ERROR == Error );
Ctxt.SScope = FindSScope( Server, Scope->SuperScopeId );
Ctxt.Scope = Scope;
Error = Callback( &Ctxt );
if( ERROR_KEY_DELETED == Error ) {
//
// Delete this scope
//
MemArrayDelElement(
&Server->Subnets, &Loc, &Scope );
MemSubnetFree( Scope );
Error = MemArrayAdjustLocation(
&Server->Subnets, &Loc );
} else {
if( NO_ERROR != Error ) return Error;
Error = MemArrayNextLoc( &Server->Subnets, &Loc );
}
}
if( ERROR_FILE_NOT_FOUND == Error ) Error = NO_ERROR;
return Error;
}
DWORD
IterateScopeRanges(
IN PM_SUBNET Scope,
IN PVOID ExtraCtxt,
IN DWORD (*Callback)( IN OUT PMM_ITERATE_CTXT )
)
{
ARRAY_LOCATION Loc;
DWORD Error;
MM_ITERATE_CTXT Ctxt;
PM_RANGE Range;
Ctxt.ExtraCtxt = ExtraCtxt;
Ctxt.Server = (PM_SERVER)Scope->ServerPtr;
Error = MemArrayInitLoc( &Scope->Ranges, &Loc );
while( NO_ERROR == Error ) {
Error = MemArrayGetElement(
&Scope->Ranges, &Loc, &Range );
ASSERT( NO_ERROR == Error );
Ctxt.Range = Range;
Error = Callback( &Ctxt );
if( NO_ERROR != Error ) return Error;
Error = MemArrayNextLoc( &Scope->Ranges, &Loc );
}
if( ERROR_FILE_NOT_FOUND == Error ) Error = NO_ERROR;
return Error;
}
DWORD
IterateScopeExclusions(
IN PM_SUBNET Scope,
IN PVOID ExtraCtxt,
IN DWORD (*Callback)( IN OUT PMM_ITERATE_CTXT )
)
{
ARRAY_LOCATION Loc;
DWORD Error;
MM_ITERATE_CTXT Ctxt;
PM_EXCL Excl;
Ctxt.ExtraCtxt = ExtraCtxt;
Ctxt.Server = (PM_SERVER)Scope->ServerPtr;
Error = MemArrayInitLoc( &Scope->Exclusions, &Loc );
while( NO_ERROR == Error ) {
Error = MemArrayGetElement(
&Scope->Exclusions, &Loc, &Excl );
ASSERT( NO_ERROR == Error );
Ctxt.Excl = Excl;
Error = Callback( &Ctxt );
if( NO_ERROR != Error ) return Error;
Error = MemArrayNextLoc( &Scope->Exclusions, &Loc );
}
if( ERROR_FILE_NOT_FOUND == Error ) Error = NO_ERROR;
return Error;
}
DWORD
IterateScopeReservations(
IN PM_SUBNET Scope,
IN PVOID ExtraCtxt,
IN DWORD (*Callback)( IN OUT PMM_ITERATE_CTXT )
)
{
ARRAY_LOCATION Loc;
DWORD Error;
MM_ITERATE_CTXT Ctxt;
PM_RESERVATION Res;
Ctxt.ExtraCtxt = ExtraCtxt;
Ctxt.Server = (PM_SERVER)Scope->ServerPtr;
Error = MemArrayInitLoc( &Scope->Reservations, &Loc );
while( NO_ERROR == Error ) {
Error = MemArrayGetElement(
&Scope->Reservations, &Loc, &Res );
ASSERT( NO_ERROR == Error );
Ctxt.Res = Res;
Error = Callback( &Ctxt );
if( NO_ERROR != Error ) return Error;
Error = MemArrayNextLoc( &Scope->Reservations, &Loc );
}
if( ERROR_FILE_NOT_FOUND == Error ) Error = NO_ERROR;
return Error;
}