windows-nt/Source/XPSP1/NT/net/rras/rtmv2/rtmlist.c
2020-09-26 16:20:57 +08:00

479 lines
10 KiB
C

/*++
Copyright (c) 1997 - 98, Microsoft Corporation
Module Name:
rtmlist.c
Abstract:
Contains routines for managing entity-specific
list of routes in RTM.
Author:
Chaitanya Kodeboyina (chaitk) 10-Sep-1998
Revision History:
--*/
#include "pchrtm.h"
#pragma hdrstop
DWORD
WINAPI
RtmCreateRouteList (
IN RTM_ENTITY_HANDLE RtmRegHandle,
OUT PRTM_ROUTE_LIST_HANDLE RouteListHandle
)
/*++
Routine Description:
Creates a list in which the caller can keep routes owned
by it.
Arguments:
RtmRegHandle - RTM registration handle for calling entity
RouteListHandle - Handle to the new route list is returned
Return Value:
Status of the operation
--*/
{
PENTITY_INFO Entity;
PROUTE_LIST RouteList;
VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
//
// Create and initialize a new route list
//
RouteList = (PROUTE_LIST) AllocNZeroObject(sizeof(ROUTE_LIST));
if (RouteList == NULL)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
#if DBG_HDL
RouteList->ListHeader.ObjectHeader.TypeSign = ROUTE_LIST_ALLOC;
RouteList->ListHeader.HandleType = ROUTE_LIST_TYPE;
#endif
InitializeListHead(&RouteList->ListHead);
#if DBG_HDL
//
// Insert into list of handles opened by entity
//
ACQUIRE_OPEN_HANDLES_LOCK(Entity);
InsertTailList(&Entity->OpenHandles, &RouteList->ListHeader.HandlesLE);
RELEASE_OPEN_HANDLES_LOCK(Entity);
#endif
REFERENCE_ENTITY(Entity, LIST_REF);
//
// Make a handle to the route list and return
//
*RouteListHandle = MAKE_HANDLE_FROM_POINTER(RouteList);
return NO_ERROR;
}
DWORD
WINAPI
RtmInsertInRouteList (
IN RTM_ENTITY_HANDLE RtmRegHandle,
IN RTM_ROUTE_LIST_HANDLE RouteListHandle OPTIONAL,
IN UINT NumRoutes,
IN PRTM_ROUTE_HANDLE RouteHandles
)
/*++
Routine Description:
Inserts a set of routes into the route list. If any route
is already in another route list, it is removed from this
old list in the process.
Arguments:
RtmRegHandle - RTM registration handle for calling entity
RouteListHandle - Handle to the route list into which we are
moving the routes to; if this argument is
NULL then we are just removing the routes
from the route lists to which they belonged
NumRoutes - Num. of route handles in the input buffer
RouteHandles - Array of handles to insert into the new list
Return Value:
Status of the operation
--*/
{
PENTITY_INFO Entity;
PROUTE_LIST RouteList;
PROUTE_INFO Route;
UINT i;
VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
RouteList = NULL;
if (ARGUMENT_PRESENT(RouteListHandle))
{
VALIDATE_ROUTE_LIST_HANDLE(RouteListHandle, &RouteList);
}
ACQUIRE_ROUTE_LISTS_WRITE_LOCK(Entity);
for (i = 0; i < NumRoutes; i++)
{
Route = ROUTE_FROM_HANDLE(RouteHandles[i]);
ASSERT(Route->RouteInfo.RouteOwner == RtmRegHandle);
//
// Remove from old list if it was present in one
//
if (!IsListEmpty(&Route->RouteListLE))
{
RemoveEntryList(&Route->RouteListLE);
DEREFERENCE_ROUTE(Route, LIST_REF);
}
//
// Insert in the new list if a new list is specified
//
if (RouteList)
{
InsertTailList(&RouteList->ListHead, &Route->RouteListLE);
REFERENCE_ROUTE(Route, LIST_REF);
}
}
RELEASE_ROUTE_LISTS_WRITE_LOCK(Entity);
return NO_ERROR;
}
DWORD
WINAPI
RtmCreateRouteListEnum (
IN RTM_ENTITY_HANDLE RtmRegHandle,
IN RTM_ROUTE_LIST_HANDLE RouteListHandle,
OUT PRTM_ENUM_HANDLE RtmEnumHandle
)
/*++
Routine Description:
Creates a enumeration on routes in the specified route list.
Arguments:
RtmRegHandle - RTM registration handle for calling entity,
RouteListHandle - Handle to route list whose routes we want,
RtmEnumHandle - Handle to this enumeration, which is used
in calls to get routes in the route list
Return Value:
Status of the operation
--*/
{
PENTITY_INFO Entity;
PROUTE_LIST RouteList;
PLIST_ENUM Enum;
VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
VALIDATE_ROUTE_LIST_HANDLE(RouteListHandle, &RouteList);
//
// Create and initialize an list enumeration block
//
Enum = (PLIST_ENUM) AllocNZeroObject(sizeof(LIST_ENUM));
if (Enum == NULL)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
#if DBG_HDL
Enum->EnumHeader.ObjectHeader.TypeSign = LIST_ENUM_ALLOC;
#endif
Enum->EnumHeader.HandleType = LIST_ENUM_TYPE;
Enum->RouteList = RouteList;
//
// Insert marker into the route list
//
ACQUIRE_ROUTE_LISTS_WRITE_LOCK(Entity);
InsertHeadList(&RouteList->ListHead, &Enum->MarkerRoute.RouteListLE);
RELEASE_ROUTE_LISTS_WRITE_LOCK(Entity);
#if DBG_HDL
//
// Insert into the list of handles opened by entity
//
ACQUIRE_OPEN_HANDLES_LOCK(Entity);
InsertTailList(&Entity->OpenHandles,&Enum->EnumHeader.HandlesLE);
RELEASE_OPEN_HANDLES_LOCK(Entity);
#endif
REFERENCE_ENTITY(Entity, ENUM_REF);
//
// Make a handle to the enum block and return
//
*RtmEnumHandle = MAKE_HANDLE_FROM_POINTER(Enum);
return NO_ERROR;
}
DWORD
WINAPI
RtmGetListEnumRoutes (
IN RTM_ENTITY_HANDLE RtmRegHandle,
IN RTM_ENUM_HANDLE EnumHandle,
IN OUT PUINT NumRoutes,
OUT PRTM_ROUTE_HANDLE RouteHandles
)
/*++
Routine Description:
Enumerates a set of routes in the route list starting from
a specific route (if given) or the start of the route list.
Arguments:
RtmRegHandle - RTM registration handle for calling entity,
EnumHandle - Handle to enumeration on the route list,
NumRoutes - Max. number of routes to fill is passed in,
Num. of routes actually copied is returned.
RouteHandles - Output buffer where route handles are retd.
Return Value:
Status of the operation
--*/
{
PENTITY_INFO Entity;
PLIST_ENUM ListEnum;
PROUTE_INFO Route;
UINT RoutesInput;
PLIST_ENTRY p;
RoutesInput = *NumRoutes;
*NumRoutes = 0;
//
// Do some validation checks on the input params
//
VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
VALIDATE_LIST_ENUM_HANDLE(EnumHandle, &ListEnum);
if (RoutesInput > Entity->OwningAddrFamily->MaxHandlesInEnum)
{
return ERROR_INVALID_PARAMETER;
}
//
// List routes starting from the enum's marker route
//
ACQUIRE_ROUTE_LISTS_WRITE_LOCK(Entity);
for (p = ListEnum->MarkerRoute.RouteListLE.Flink;
p != &ListEnum->RouteList->ListHead;
p = p->Flink)
{
if (*NumRoutes >= RoutesInput)
{
break;
}
Route = CONTAINING_RECORD(p, ROUTE_INFO, RouteListLE);
//
// If this route is not a marker route, copy handle
//
if (Route->RouteInfo.DestHandle)
{
RouteHandles[(*NumRoutes)++] = MAKE_HANDLE_FROM_POINTER(Route);
REFERENCE_ROUTE(Route, HANDLE_REF);
}
}
//
// Re-adjust the marker to reflect its new posn
//
RemoveEntryList(&ListEnum->MarkerRoute.RouteListLE);
InsertTailList(p, &ListEnum->MarkerRoute.RouteListLE);
RELEASE_ROUTE_LISTS_WRITE_LOCK(Entity);
return NO_ERROR;
}
DWORD
WINAPI
RtmDeleteRouteList (
IN RTM_ENTITY_HANDLE RtmRegHandle,
IN RTM_ROUTE_LIST_HANDLE RouteListHandle
)
/*++
Routine Description:
Removes all routes on an entity specific list and frees
resources allocated to it.
Arguments:
RtmRegHandle - RTM registration handle for calling entity,
RouteListHandle - Handle to the route list to delete.
Return Value:
Status of the operation
--*/
{
PENTITY_INFO Entity;
PROUTE_LIST RouteList;
PLIST_ENUM Enum;
PROUTE_INFO Route;
PLIST_ENTRY p;
VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
VALIDATE_ROUTE_LIST_HANDLE(RouteListHandle, &RouteList);
ACQUIRE_ROUTE_LISTS_WRITE_LOCK(Entity);
//
// Remove each route from the route list
//
while (!IsListEmpty(&RouteList->ListHead))
{
p = RemoveHeadList(&RouteList->ListHead);
Route = CONTAINING_RECORD(p, ROUTE_INFO, RouteListLE);
if (Route->RouteInfo.DestHandle)
{
// This is an actual route in the list
DEREFERENCE_ROUTE(Route, LIST_REF);
}
else
{
// This is a marker route for an enum
Enum = CONTAINING_RECORD(Route, LIST_ENUM, MarkerRoute);
#if DBG_HDL
//
// Remove from the list of handles opened by entity
//
ACQUIRE_OPEN_HANDLES_LOCK(Entity);
RemoveEntryList(&Enum->EnumHeader.HandlesLE);
RELEASE_OPEN_HANDLES_LOCK(Entity);
#endif
DEREFERENCE_ENTITY(Entity, ENUM_REF);
// Free the memory allocated for the enum and continue
#if DBG_HDL
Enum->EnumHeader.ObjectHeader.TypeSign = LIST_ENUM_FREED;
#endif
FreeObject(Enum);
}
}
RELEASE_ROUTE_LISTS_WRITE_LOCK(Entity);
#if DBG_HDL
//
// Remove from the list of handles opened by entity
//
ACQUIRE_OPEN_HANDLES_LOCK(Entity);
RemoveEntryList(&RouteList->ListHeader.HandlesLE);
RELEASE_OPEN_HANDLES_LOCK(Entity);
#endif
DEREFERENCE_ENTITY(Entity, LIST_REF);
// Free the memory allocated for the list and return
#if DBG_HDL
RouteList->ListHeader.ObjectHeader.TypeSign = ROUTE_LIST_FREED;
#endif
FreeObject(RouteList);
return NO_ERROR;
}