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

328 lines
7 KiB
C

/*++
Copyright (c) 1997 - 98, Microsoft Corporation
Module Name:
rtmmetd.c
Abstract:
Contains routines that deals with invocation
of methods that entities export to other
entities for the purpose of interpreting
entity specific data.
Author:
Chaitanya Kodeboyina (chaitk) 22-Aug-1998
Revision History:
--*/
#include "pchrtm.h"
#pragma hdrstop
DWORD
WINAPI
RtmGetEntityMethods (
IN RTM_ENTITY_HANDLE RtmRegHandle,
IN RTM_ENTITY_HANDLE EntityHandle,
IN OUT PUINT NumMethods,
OUT PRTM_ENTITY_EXPORT_METHOD ExptMethods
)
/*++
Routine Description:
Retrieves the set of methods exported by a given entity.
Arguments:
RtmRegHandle - RTM registration handle for calling entity,
EntityHandle - RTM handle for entity whose methods we want,
NumMethods - Number of methods that can be filled
is passed in, and number of methods
exported by this entity is returned,
ExptMethods - Set of methods requested by the caller.
Return Value:
Status of the operation
--*/
{
PRTM_ENTITY_EXPORT_METHODS EntityMethods;
PENTITY_INFO Entity;
DWORD Status;
DBG_VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
VALIDATE_ENTITY_HANDLE(EntityHandle, &Entity);
EntityMethods = &Entity->EntityMethods;
//
// Does the caller just need number of methods ?
//
if (*NumMethods == 0)
{
*NumMethods = EntityMethods->NumMethods;
return NO_ERROR;
}
//
// Check if we have space to copy all methods
//
if (EntityMethods->NumMethods > *NumMethods)
{
Status = ERROR_INSUFFICIENT_BUFFER;
}
else
{
Status = NO_ERROR;
*NumMethods = EntityMethods->NumMethods;
}
//
// Copy as many methods as u can fit in output
//
ASSERT(ExptMethods != NULL);
CopyMemory(ExptMethods,
EntityMethods->Methods,
*NumMethods * sizeof(RTM_ENTITY_EXPORT_METHOD));
*NumMethods = EntityMethods->NumMethods;
return Status;
}
DWORD
WINAPI
RtmInvokeMethod (
IN RTM_ENTITY_HANDLE RtmRegHandle,
IN RTM_ENTITY_HANDLE EntityHandle,
IN PRTM_ENTITY_METHOD_INPUT Input,
IN OUT PUINT OutputSize,
OUT PRTM_ENTITY_METHOD_OUTPUT Output
)
/*++
Routine Description:
Invokes a method exported by another entity
Arguments:
RtmRegHandle - RTM registration handle for calling entity,
EntityHandle - Handle for entity whose method we are invoking,
Input - Input buffer with the following information
- Methods to be invoked,
- Common Input buffer to all these methods,
OutputSize - Size of the output buffer is passed in, and
the number of bytes filled in output is retd,
Output - Output buffer that is filled in the format of
a series of (Method Id, Corr. Output) tuples
Return Value:
Status of the operation
--*/
{
PRTM_ENTITY_EXPORT_METHODS EntityMethods;
PENTITY_INFO Entity;
DWORD MethodsCalled;
DWORD MethodsLeft;
UINT OutputHdrSize;
UINT OutBytes;
UINT BytesTotal;
UINT BytesLeft;
UINT i;
BytesTotal = BytesLeft = *OutputSize;
*OutputSize = 0;
DBG_VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
//
// Validate the entity and target handles passed in
//
VALIDATE_ENTITY_HANDLE(EntityHandle, &Entity);
//
// Call each method in 'methods to be called' mask.
//
MethodsCalled = MethodsLeft = Input->MethodType;
ACQUIRE_ENTITY_METHODS_READ_LOCK(Entity);
if (Entity->State == ENTITY_STATE_DEREGISTERED)
{
RELEASE_ENTITY_METHODS_READ_LOCK(Entity);
return ERROR_INVALID_HANDLE;
}
OutputHdrSize = FIELD_OFFSET(RTM_ENTITY_METHOD_OUTPUT, OutputData);
EntityMethods = &Entity->EntityMethods;
for (i = 0; (i < EntityMethods->NumMethods) && (MethodsLeft); i++)
{
//
// Do we have bytes left for next method's output ?
//
if (BytesLeft < OutputHdrSize)
{
break;
}
//
// If next method in list, prepare input and invoke
//
if (MethodsLeft & 0x01)
{
Input->MethodType = Output->MethodType = (1 << i);
Output->OutputSize = BytesLeft - OutputHdrSize;
//
// Initialize the output params of this method
//
Output->OutputSize = 0;
Output->MethodStatus = ERROR_NOT_SUPPORTED;
//
// If method supported, invoke with input/output
//
if (EntityMethods->Methods[i])
{
EntityMethods->Methods[i](RtmRegHandle,
EntityHandle,
Input,
Output);
}
OutBytes = Output->OutputSize + OutputHdrSize;
Output = (PRTM_ENTITY_METHOD_OUTPUT) (OutBytes + (PUCHAR) Output);
BytesLeft -= OutBytes;
}
MethodsLeft >>= 1;
}
RELEASE_ENTITY_METHODS_READ_LOCK(Entity);
Input->MethodType = MethodsCalled;
*OutputSize = BytesTotal - BytesLeft;
return NO_ERROR;
}
DWORD
WINAPI
RtmBlockMethods (
IN RTM_ENTITY_HANDLE RtmRegHandle,
IN HANDLE TargetHandle OPTIONAL,
IN UCHAR TargetType OPTIONAL,
IN DWORD BlockingFlag
)
/*++
Routine Description:
Blocks or unblocks the execution of methods on the target
handle or on all targets if the target handle is NULL.
Arguments:
RtmRegHandle - RTM registration handle for calling entity,
TargetHandle - Destination, Route or NextHop Handle
TargetType - Type of the TargetHandle (DEST_TYPE, ...)
BlockingFlag - RTM_BLOCK_METHODS or RTM_RESUME_METHODS
to block, unblock method invocations resp.
Return Value:
Status of the operation
--*/
{
PENTITY_INFO Entity;
VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
UNREFERENCED_PARAMETER(TargetType);
UNREFERENCED_PARAMETER(TargetHandle);
#if DBG
//
// No method locks on the target used at present
//
if (ARGUMENT_PRESENT(TargetHandle))
{
PVOID Target;
VALIDATE_OBJECT_HANDLE(TargetHandle, TargetType, &Target);
}
#endif
if (BlockingFlag == RTM_BLOCK_METHODS)
{
ACQUIRE_ENTITY_METHODS_WRITE_LOCK(Entity);
}
else
{
RELEASE_ENTITY_METHODS_WRITE_LOCK(Entity);
}
return NO_ERROR;
}