|
|
/*++
Copyright (c) 1997-1998 Microsoft Corporation
Module Name:
rtmmain.h
Abstract: Private defs for Routing Table Manager DLL
Author: Chaitanya Kodeboyina (chaitk) 17-Aug-1998
Revision History:
--*/
#ifndef __ROUTING_RTMMAIN_H__
#define __ROUTING_RTMMAIN_H__
//
// Common Header for all RTM internal structures
//
// Disable warnings for unnamed structs
#pragma warning(disable : 4201)
typedef struct _OBJECT_HEADER { #if DBG_HDL
union { DWORD TypeSign; // Type & unique signature for object
struct { CHAR Type; // Identifies type of the object
CHAR Signature[2]; // Pattern unique for an object type
CHAR Alloc; // Set + if allocated, - if freed
}; }; #endif
#if DBG_MEM
LIST_ENTRY AllocLE; // On list of all memory allocations
#endif
LONG RefCount; // Reference count for this object
#if DBG_REF
LONG RefTypes[MAX_REFS]; // Nature of references on the object
#endif
} OBJECT_HEADER, *POBJECT_HEADER;
#pragma warning(default : 4201)
//
// Defns to validate handles & convert them to pointers
//
#define HANDLE_CONV_KEY \
(ULONG_PTR)(('RTM2') | ('RTM2' << (sizeof(PVOID) - 4)))
#define MAKE_HANDLE_FROM_POINTER(ObjectHandle) \
(HANDLE) (((ULONG_PTR) ObjectHandle) ^ HANDLE_CONV_KEY)
#define GET_POINTER_FROM_HANDLE(ObjectHandle) \
(PVOID) (((ULONG_PTR) ObjectHandle) ^ HANDLE_CONV_KEY)
PVOID __inline GetObjectFromHandle(HANDLE ObjectHandle, UCHAR ObjectType) { POBJECT_HEADER ObjHdr = GET_POINTER_FROM_HANDLE(ObjectHandle);
UNREFERENCED_PARAMETER(ObjectType);
#if DBG_HDL
try { if (ObjHdr->TypeSign != OBJECT_SIGNATURE[ObjectType]) { if (ObjectType != GENERIC_TYPE) { ObjHdr = NULL; } } } except(EXCEPTION_EXECUTE_HANDLER) { ObjHdr = NULL; } #endif
return ObjHdr; }
#define OBJECT_FROM_HANDLE(ObjectHandle, ObjectType) \
(POBJECT_HEADER) GetObjectFromHandle(ObjectHandle, ObjectType);
#define VALIDATE_OBJECT_HANDLE(ObjectHandle, ObjectType, pObject) \
*pObject = (PVOID) OBJECT_FROM_HANDLE(ObjectHandle, ObjectType);\ if ((!*pObject)) \ { \ return ERROR_INVALID_HANDLE; \ } \
#define ENTITY_FROM_HANDLE(EntityHandle) \
(PENTITY_INFO) GetObjectFromHandle(EntityHandle, ENTITY_TYPE)
#define VALIDATE_ENTITY_HANDLE(EntityHandle, pEntity) \
*pEntity = ENTITY_FROM_HANDLE(EntityHandle); \ if ((!*pEntity)||((*pEntity)->State==ENTITY_STATE_DEREGISTERED))\ { \ return ERROR_INVALID_HANDLE; \ } \
#define DBG_VALIDATE_ENTITY_HANDLE(EntityHandle, pEntity) \
UNREFERENCED_PARAMETER(EntityHandle); \ DBG_UNREFERENCED_LOCAL_VARIABLE(*pEntity); \ if (DBG_HDL) \ { \ VALIDATE_ENTITY_HANDLE(EntityHandle, pEntity) \ }
#define DEST_FROM_HANDLE(DestHandle) \
(PDEST_INFO) GetObjectFromHandle(DestHandle, DEST_TYPE)
#define VALIDATE_DEST_HANDLE(DestHandle, pDest) \
*pDest = DEST_FROM_HANDLE(DestHandle); \ if ((!(*pDest)) || ((*pDest)->State == DEST_STATE_DELETED)) \ { \ return ERROR_INVALID_HANDLE; \ } \
#define ROUTE_FROM_HANDLE(RouteHandle) \
(PROUTE_INFO) GetObjectFromHandle(RouteHandle, ROUTE_TYPE)
#define VALIDATE_ROUTE_HANDLE(RouteHandle, pRoute) \
*pRoute = ROUTE_FROM_HANDLE(RouteHandle); \ if ( \ (!(*pRoute)) || \ ((*pRoute)->RouteInfo.State == RTM_ROUTE_STATE_DELETED) \ ) \ { \ return ERROR_INVALID_HANDLE; \ } \
#define NEXTHOP_FROM_HANDLE(NextHopHandle) \
(PNEXTHOP_INFO) GetObjectFromHandle(NextHopHandle, NEXTHOP_TYPE)
#define VALIDATE_NEXTHOP_HANDLE(NextHopHandle, pNextHop) \
*pNextHop = NEXTHOP_FROM_HANDLE(NextHopHandle); \ if (!(*pNextHop)) \ { \ return ERROR_INVALID_HANDLE; \ } \
#define DEST_ENUM_FROM_HANDLE(DestEnumHandle) \
(PDEST_ENUM) GetObjectFromHandle(DestEnumHandle, DEST_ENUM_TYPE)
#define VALIDATE_DEST_ENUM_HANDLE(DestEnumHandle, pDestEnum) \
*pDestEnum = DEST_ENUM_FROM_HANDLE(DestEnumHandle); \ if ((!*pDestEnum)) \ { \ return ERROR_INVALID_HANDLE; \ } \
#define ROUTE_ENUM_FROM_HANDLE(RouteEnumHandle) \
(PROUTE_ENUM) GetObjectFromHandle(RouteEnumHandle, ROUTE_ENUM_TYPE)
#define VALIDATE_ROUTE_ENUM_HANDLE(RouteEnumHandle, pRouteEnum) \
*pRouteEnum = ROUTE_ENUM_FROM_HANDLE(RouteEnumHandle); \ if ((!*pRouteEnum)) \ { \ return ERROR_INVALID_HANDLE; \ } \
#define NEXTHOP_ENUM_FROM_HANDLE(EnumHandle) \
(PNEXTHOP_ENUM) GetObjectFromHandle(EnumHandle, NEXTHOP_ENUM_TYPE)
#define VALIDATE_NEXTHOP_ENUM_HANDLE(NextHopEnumHandle, pNextHopEnum) \
*pNextHopEnum = NEXTHOP_ENUM_FROM_HANDLE(NextHopEnumHandle); \ if ((!*pNextHopEnum)) \ { \ return ERROR_INVALID_HANDLE; \ } \
#define NOTIFY_FROM_HANDLE(NotifyHandle) \
(PNOTIFY_INFO) GetObjectFromHandle(NotifyHandle, NOTIFY_TYPE)
#define VALIDATE_NOTIFY_HANDLE(NotifyHandle, pNotify) \
*pNotify = NOTIFY_FROM_HANDLE(NotifyHandle); \ if ((!*pNotify) || ((*pNotify)->CNIndex < 0)) \ { \ return ERROR_INVALID_HANDLE; \ } \
#define ROUTE_LIST_FROM_HANDLE(ListHandle) \
(PROUTE_LIST) GetObjectFromHandle(ListHandle, ROUTE_LIST_TYPE)
#define VALIDATE_ROUTE_LIST_HANDLE(ListHandle, pList) \
*pList = ROUTE_LIST_FROM_HANDLE(ListHandle); \ if ((!*pList)) \ { \ return ERROR_INVALID_HANDLE; \ } \
#define LIST_ENUM_FROM_HANDLE(ListEnumHandle) \
(PLIST_ENUM) GetObjectFromHandle(ListEnumHandle, LIST_ENUM_TYPE)
#define VALIDATE_LIST_ENUM_HANDLE(ListEnumHandle, pListEnum) \
*pListEnum = LIST_ENUM_FROM_HANDLE(ListEnumHandle); \ if ((!*pListEnum)) \ { \ return ERROR_INVALID_HANDLE; \ } \
//
// Defns used to maintain reference count on structures
//
ULONG __inline InitializeObjectReference(POBJECT_HEADER Object, UCHAR RefType) { UNREFERENCED_PARAMETER(RefType);
#if DBG_REF
InterlockedIncrement(&Object->RefTypes[RefType]); #endif
return InterlockedIncrement(&Object->RefCount); }
ULONG __inline ReferenceObject(POBJECT_HEADER Object, UCHAR RefType) { UNREFERENCED_PARAMETER(RefType);
// Once ref falls to 0, this should never happen
ASSERT(Object->RefCount > 0);
#if DBG_REF
ASSERT(Object->RefTypes[RefType] >= 0);
InterlockedIncrement(&Object->RefTypes[RefType]); #endif
return InterlockedIncrement(&Object->RefCount); }
ULONG __inline DereferenceObject(POBJECT_HEADER Object, UCHAR RefType) { UNREFERENCED_PARAMETER(RefType);
// Ref count should be +ve before we decrement it
ASSERT(Object->RefCount > 0);
#if DBG_REF
ASSERT(Object->RefTypes[RefType] > 0);
InterlockedDecrement(&Object->RefTypes[RefType]); #endif
return InterlockedDecrement(&Object->RefCount); }
#define INITIALIZE_INSTANCE_REFERENCE(Instance, RefType) \
InitializeObjectReference(&Instance->ObjectHeader, RefType);
#define REFERENCE_INSTANCE(Instance, RefType) \
ReferenceObject(&Instance->ObjectHeader, RefType);
#define DEREFERENCE_INSTANCE(Instance, RefType) \
if (DereferenceObject(&Instance->ObjectHeader, RefType) == 0) \ DestroyInstance(Instance);
#define INITIALIZE_ADDR_FAMILY_REFERENCE(Instance, RefType) \
InitializeObjectReference(&Instance->ObjectHeader, RefType);
#define REFERENCE_ADDR_FAMILY(AddrFamilyInfo, RefType) \
ReferenceObject(&AddrFamilyInfo->ObjectHeader, RefType);
#define DEREFERENCE_ADDR_FAMILY(AddrFamInfo, RefType) \
if (DereferenceObject(&AddrFamInfo->ObjectHeader,RefType) == 0) \ DestroyAddressFamily(AddrFamInfo);
#define INITIALIZE_ENTITY_REFERENCE(Entity, RefType) \
InitializeObjectReference(&Entity->ObjectHeader, RefType);
#define REFERENCE_ENTITY(Entity, RefType) \
ReferenceObject(&Entity->ObjectHeader, RefType);
#define DEREFERENCE_ENTITY(Entity, RefType) \
if (DereferenceObject(&Entity->ObjectHeader, RefType) == 0) \ DestroyEntity(Entity);
#define INITIALIZE_DEST_REFERENCE(Dest, RefType) \
InitializeObjectReference(&(Dest)->ObjectHeader, RefType);
#define REFERENCE_DEST(Dest, RefType) \
ReferenceObject(&(Dest)->ObjectHeader, RefType);
#define DEREFERENCE_DEST(Dest, RefType) \
if (DereferenceObject(&(Dest)->ObjectHeader, RefType) == 0) \ DestroyDest(Dest);
#define INITIALIZE_ROUTE_REFERENCE(Route, RefType) \
InitializeObjectReference(&(Route)->ObjectHeader, RefType);
#define REFERENCE_ROUTE(Route, RefType) \
ReferenceObject(&(Route)->ObjectHeader, RefType);
#define DEREFERENCE_ROUTE(Route, RefType) \
if (DereferenceObject(&(Route)->ObjectHeader, RefType) == 0) \ DestroyRoute(Route);
#define INITIALIZE_NEXTHOP_REFERENCE(NextHop, RefType) \
InitializeObjectReference(&(NextHop)->ObjectHeader, RefType);
#define REFERENCE_NEXTHOP(NextHop, RefType) \
ReferenceObject(&(NextHop)->ObjectHeader, RefType);
#define DEREFERENCE_NEXTHOP(NextHop, RefType) \
if (DereferenceObject(&(NextHop)->ObjectHeader, RefType) == 0) \ DestroyNextHop(NextHop);
//
// Macros used to lock structures using critical sections
//
#define CREATE_LOCK(Lock) \
InitializeCriticalSection((Lock))
#define DELETE_LOCK(Lock) \
DeleteCriticalSection((Lock))
#define ACQUIRE_LOCK(Lock) \
EnterCriticalSection((Lock))
#define RELEASE_LOCK(Lock) \
LeaveCriticalSection((Lock))
//
// Macros used to lock structures in read or write mode
//
typedef RTL_RESOURCE READ_WRITE_LOCK, *PREAD_WRITE_LOCK;
#define CREATE_READ_WRITE_LOCK(pRWL) \
RtlInitializeResource((pRWL))
#define DELETE_READ_WRITE_LOCK(pRWL) \
RtlDeleteResource((pRWL))
#define READ_WRITE_LOCK_CREATED(pRWL) (TRUE)
#define ACQUIRE_READ_LOCK(pRWL) \
RtlAcquireResourceShared((pRWL),TRUE)
#define RELEASE_READ_LOCK(pRWL) \
RtlReleaseResource((pRWL))
#define ACQUIRE_WRITE_LOCK(pRWL) \
RtlAcquireResourceExclusive((pRWL),TRUE)
#define RELEASE_WRITE_LOCK(pRWL) \
RtlReleaseResource((pRWL))
#define READ_LOCK_TO_WRITE_LOCK(pRWL) \
RtlConvertSharedToExclusive((pRWL))
#define WRITE_LOCK_TO_READ_LOCK(pRWL) \
RtlConvertExclusiveToShared((pRWL))
//
// Macros to acquire and release dynamic R/W locks
// [ This has been borrowed from the MGM libary ]
//
#define ACQUIRE_DYNAMIC_READ_LOCK(ppRWL) \
AcquireReadLock((PMGM_READ_WRITE_LOCK *)ppRWL)
#define RELEASE_DYNAMIC_READ_LOCK(ppRWL) \
ReleaseReadLock((PMGM_READ_WRITE_LOCK *)ppRWL)
#define ACQUIRE_DYNAMIC_WRITE_LOCK(ppRWL) \
AcquireWriteLock((PMGM_READ_WRITE_LOCK *)ppRWL)
#define RELEASE_DYNAMIC_WRITE_LOCK(ppRWL) \
ReleaseWriteLock((PMGM_READ_WRITE_LOCK *)ppRWL)
//
// Macros used in allocating and operating on memory
//
#define ZeroMemory RtlZeroMemory
#define CopyMemory RtlCopyMemory
#define CompareMemory RtlEqualMemory
#define AllocOnStack(nb) _alloca((nb))
#define AllocMemory(nb) HeapAlloc(RtmGlobals.GlobalHeap, \
0, \ (nb))
#define AllocNZeroMemory(nb) HeapAlloc(RtmGlobals.GlobalHeap, \
HEAP_ZERO_MEMORY, \ (nb))
#define FreeMemory(ptr) HeapFree(RtmGlobals.GlobalHeap, \
0, \ (ptr))
#if !DBG_MEM
#define AllocNZeroObject(nb) AllocNZeroMemory(nb)
#else
PVOID __inline AllocNZeroObject(UINT NumBytes) { OBJECT_HEADER *Object;
Object = AllocNZeroMemory(NumBytes);
if (Object) {
ACQUIRE_ALLOCS_LIST_LOCK(); InsertTailList(&RtmGlobals.AllocsList, &Object->AllocLE); RELEASE_ALLOCS_LIST_LOCK(); }
return Object; }
#endif
#if !DBG_MEM
#define FreeObject(ptr) FreeMemory(ptr)
#else
VOID __inline FreeObject(PVOID Object) { ACQUIRE_ALLOCS_LIST_LOCK(); RemoveEntryList(&((POBJECT_HEADER)Object)->AllocLE); RELEASE_ALLOCS_LIST_LOCK();
FreeMemory(Object); }
#endif
//
// Other Misc Macros
//
DWORD __inline NumBitsInDword (DWORD Dword) { DWORD NumBits = 0;
while (Dword) { Dword &= (Dword - 1);
NumBits++; }
return NumBits; }
#define NUMBER_OF_BITS NumBitsInDword
//
// Error Handling and other related macros
//
#define SUCCESS(code) (code == NO_ERROR)
//
// DLL Startup, Cleanup Functions and Macros
//
BOOL RtmDllStartup( VOID );
BOOL RtmDllCleanup( VOID );
DWORD RtmApiStartup( VOID );
#define CHECK_FOR_RTM_API_INITIALIZED() \
if (!RtmGlobals.ApiInitialized) \ { \ Status = RtmApiStartup(); \ \ if (Status != NO_ERROR) \ { \ return Status; \ } \ } \
#endif //__ROUTING_RTMMAIN_H__
|