/*++ Copyright (C) 2000 Microsoft Corporation Module Name: iterate.c Abstract: This module contains routines that iterate over the MM data structures --*/ #include 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 ); 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; }