windows-nt/Source/XPSP1/NT/net/rras/ip/nathlp/h323/rmh323.cpp
2020-09-26 16:20:57 +08:00

1103 lines
19 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1998, Microsoft Corporation
Module Name:
rmh323.c
Abstract:
This module contains routines for the H.323 transparent proxy module's
interface to the IP router-manager. (See ROUTPROT.H for details).
Author:
Abolade Gbadegesin (aboladeg) 18-Jun-1999
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
#include <h323icsp.h>
COMPONENT_REFERENCE H323ComponentReference;
PIP_H323_GLOBAL_INFO H323GlobalInfo = NULL;
CRITICAL_SECTION H323GlobalInfoLock;
HANDLE H323NotificationEvent;
ULONG H323ProtocolStopped = 0;
const MPR_ROUTING_CHARACTERISTICS H323RoutingCharacteristics =
{
MS_ROUTER_VERSION,
MS_IP_H323,
RF_ROUTING|RF_ADD_ALL_INTERFACES,
H323RmStartProtocol,
H323RmStartComplete,
H323RmStopProtocol,
H323RmGetGlobalInfo,
H323RmSetGlobalInfo,
NULL,
NULL,
H323RmAddInterface,
H323RmDeleteInterface,
H323RmInterfaceStatus,
H323RmGetInterfaceInfo,
H323RmSetInterfaceInfo,
H323RmGetEventMessage,
NULL,
NULL,
NULL,
NULL,
NULL,
H323RmMibCreate,
H323RmMibDelete,
H323RmMibGet,
H323RmMibSet,
H323RmMibGetFirst,
H323RmMibGetNext,
NULL,
NULL
};
SUPPORT_FUNCTIONS H323SupportFunctions;
VOID
H323CleanupModule(
VOID
)
/*++
Routine Description:
This routine is invoked to cleanup the H.323 transparent proxy module.
Arguments:
none.
Return Value:
none.
Environment:
Invoked from within a 'DllMain' routine on 'DLL_PROCESS_DETACH'.
--*/
{
// TODO: Call h323ics!CleanupModule
H323ProxyCleanupModule();
H323ShutdownInterfaceManagement();
DeleteCriticalSection(&H323GlobalInfoLock);
DeleteComponentReference(&H323ComponentReference);
} // H323CleanupModule
VOID
H323CleanupProtocol(
VOID
)
/*++
Routine Description:
This routine is invoked to cleanup the H.323 transparent proxy
protocol-component after a 'StopProtocol'. It runs when the last reference
to the component is released. (See 'COMPREF.H').
Arguments:
none.
Return Value:
none.
Environment:
Invoked from within an arbitrary context with no locks held.
--*/
{
PROFILE("H323CleanupProtocol");
if (H323GlobalInfo) { NH_FREE(H323GlobalInfo); H323GlobalInfo = NULL; }
// TODO: Call h323ics!StopService
H323ProxyStopService();
InterlockedExchange(reinterpret_cast<LPLONG>(&H323ProtocolStopped), 1);
SetEvent(H323NotificationEvent);
ResetComponentReference(&H323ComponentReference);
} // H323CleanupProtocol
BOOLEAN
H323InitializeModule(
VOID
)
/*++
Routine Description:
This routine is invoked to initialize the H323 module.
Arguments:
none.
Return Value:
BOOLEAN - TRUE if initialization succeeded, FALSE otherwise
Environment:
Invoked in the context of a 'DllMain' routine on 'DLL_PROCESS_ATTACH'.
--*/
{
if (InitializeComponentReference(
&H323ComponentReference, H323CleanupProtocol
)) {
return FALSE;
}
__try {
InitializeCriticalSection(&H323GlobalInfoLock);
} __except(EXCEPTION_EXECUTE_HANDLER) {
DeleteComponentReference(&H323ComponentReference);
return FALSE;
}
if (H323InitializeInterfaceManagement()) {
DeleteCriticalSection(&H323GlobalInfoLock);
DeleteComponentReference(&H323ComponentReference);
return FALSE;
}
// TODO: Call h323ics!InitializeModule
H323ProxyInitializeModule();
return TRUE;
} // H323InitializeModule
ULONG
APIENTRY
H323RmStartProtocol(
HANDLE NotificationEvent,
PSUPPORT_FUNCTIONS SupportFunctions,
PVOID GlobalInfo,
ULONG StructureVersion,
ULONG StructureSize,
ULONG StructureCount
)
/*++
Routine Description:
This routine is invoked to indicate the component's operation should begin.
Arguments:
NotificationEvent - event on which we notify the router-manager
about asynchronous occurrences
SupportFunctions - functions for initiating router-related operations
GlobalInfo - configuration for the component
Return Value:
ULONG - Win32 status code.
Environment:
The routine runs in the context of an IP router-manager thread.
--*/
{
ULONG Error = NO_ERROR;
ULONG Size;
PROFILE("H323RmStartProtocol");
REFERENCE_H323_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
if (!GlobalInfo) { DEREFERENCE_H323_AND_RETURN(ERROR_INVALID_PARAMETER); }
do {
//
// Copy the global configuration
//
EnterCriticalSection(&H323GlobalInfoLock);
Size = sizeof(*H323GlobalInfo);
H323GlobalInfo
= reinterpret_cast<PIP_H323_GLOBAL_INFO>(NH_ALLOCATE(Size));
if (!H323GlobalInfo) {
LeaveCriticalSection(&H323GlobalInfoLock);
NhTrace(
TRACE_FLAG_INIT,
"H323RmStartProtocol: cannot allocate global info"
);
NhErrorLog(
IP_H323_LOG_ALLOCATION_FAILED,
0,
"%d",
Size
);
Error = ERROR_NOT_ENOUGH_MEMORY;
break;
}
CopyMemory(H323GlobalInfo, GlobalInfo, Size);
//
// Save the notification event
//
H323NotificationEvent = NotificationEvent;
//
// Save the support functions
//
if (!SupportFunctions) {
ZeroMemory(&H323SupportFunctions, sizeof(H323SupportFunctions));
} else {
CopyMemory(
&H323SupportFunctions,
SupportFunctions,
sizeof(*SupportFunctions)
);
}
// TODO: Call h323ics!StartModule
H323ProxyStartService();
LeaveCriticalSection(&H323GlobalInfoLock);
InterlockedExchange(reinterpret_cast<LPLONG>(&H323ProtocolStopped), 0);
} while (FALSE);
DEREFERENCE_H323_AND_RETURN(Error);
} // H323RmStartProtocol
ULONG
APIENTRY
H323RmStartComplete(
VOID
)
/*++
Routine Description:
This routine is invoked when the router has finished adding the initial
configuration.
Arguments:
none.
Return Value:
ULONG - Win32 status code
Environment:
The routine runs in the context of an IP router-manager thread.
--*/
{
return NO_ERROR;
} // H323RmStartComplete
ULONG
APIENTRY
H323RmStopProtocol(
VOID
)
/*++
Routine Description:
This routine is invoked to stop the protocol.
Arguments:
none.
Return Value:
ULONG - Win32 status code
Environment:
The routine runs in the context of an IP router-manager thread.
--*/
{
//
// Reference the module to make sure it's running
//
REFERENCE_H323_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
//
// Drop the initial reference to cause a cleanup
//
ReleaseInitialComponentReference(&H323ComponentReference);
return DEREFERENCE_H323() ? NO_ERROR : ERROR_PROTOCOL_STOP_PENDING;
} // H323RmStopProtocol
ULONG
APIENTRY
H323RmAddInterface(
PWCHAR Name,
ULONG Index,
NET_INTERFACE_TYPE Type,
ULONG MediaType,
USHORT AccessType,
USHORT ConnectionType,
PVOID InterfaceInfo,
ULONG StructureVersion,
ULONG StructureSize,
ULONG StructureCount
)
/*++
Routine Description:
This routine is invoked to add an interface to the component.
Arguments:
Name - the name of the interface (unused)
Index - the index of the interface
Type - the type of the interface
InterfaceInfo - the configuration information for the interface
Return Value:
ULONG - Win32 status code.
Environment:
The routine runs in the context of an IP router-manager thread.
--*/
{
ULONG Error;
PROFILE("H323RmAddInterface");
REFERENCE_H323_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
Error =
H323CreateInterface(
Index,
Type,
(PIP_H323_INTERFACE_INFO)InterfaceInfo,
NULL
);
DEREFERENCE_H323_AND_RETURN(Error);
} // H323RmAddInterface
ULONG
APIENTRY
H323RmDeleteInterface(
ULONG Index
)
/*++
Routine Description:
This routine is invoked to delete an interface from the component.
Arguments:
Index - the index of the interface
Return Value:
ULONG - Win32 status code
Environment:
The routine runs in the context of an IP router-manager thread.
--*/
{
ULONG Error;
PROFILE("H323RmDeleteInterface");
REFERENCE_H323_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
Error =
H323DeleteInterface(
Index
);
DEREFERENCE_H323_AND_RETURN(Error);
} // H323RmDeleteInterface
ULONG
APIENTRY
H323RmGetEventMessage(
OUT ROUTING_PROTOCOL_EVENTS* Event,
OUT MESSAGE* Result
)
/*++
Routine Description:
This routine is invoked to retrieve an event message from the component.
The only event message we generate is the 'ROUTER_STOPPED' message.
Arguments:
Event - receives the generated event
Result - receives the associated result
Return Value:
ULONG - Win32 status code.
--*/
{
PROFILE("H323RmGetEventMessage");
if (InterlockedExchange(reinterpret_cast<LPLONG>(&H323ProtocolStopped), 0)) {
*Event = ROUTER_STOPPED;
return NO_ERROR;
}
return ERROR_NO_MORE_ITEMS;
} // H323RmGetEventMessage
ULONG
APIENTRY
H323RmGetInterfaceInfo(
ULONG Index,
PVOID InterfaceInfo,
IN OUT PULONG InterfaceInfoSize,
IN OUT PULONG StructureVersion,
IN OUT PULONG StructureSize,
IN OUT PULONG StructureCount
)
/*++
Routine Description:
This routine is invoked to retrieve the component's per-interface
configuration.
Arguments:
Index - the index of the interface to be queried
InterfaceInfo - receives the query results
InterfaceInfoSize - receives the amount of data retrieved
Return Value:
ULONG - Win32 status code.
--*/
{
ULONG Error;
PROFILE("H323RmGetInterfaceInfo");
REFERENCE_H323_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
Error =
H323QueryInterface(
Index,
(PIP_H323_INTERFACE_INFO)InterfaceInfo,
InterfaceInfoSize
);
*StructureSize = *InterfaceInfoSize;
if (StructureCount) {*StructureCount = 1;}
DEREFERENCE_H323_AND_RETURN(Error);
} // H323RmGetInterfaceInfo
ULONG
APIENTRY
H323RmSetInterfaceInfo(
ULONG Index,
PVOID InterfaceInfo,
ULONG StructureVersion,
ULONG StructureSize,
ULONG StructureCount
)
/*++
Routine Description:
This routine is invoked to change the component's per-interface
configuration.
Arguments:
Index - the index of the interface to be updated
InterfaceInfo - supplies the new configuration
Return Value:
ULONG - Win32 status code.
--*/
{
ULONG Error;
PROFILE("H323RmSetInterfaceInfo");
REFERENCE_H323_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
Error =
H323ConfigureInterface(
Index,
(PIP_H323_INTERFACE_INFO)InterfaceInfo
);
DEREFERENCE_H323_AND_RETURN(Error);
} // H323RmSetInterfaceInfo
ULONG
APIENTRY
H323RmInterfaceStatus(
ULONG Index,
BOOL InterfaceActive,
ULONG StatusType,
PVOID StatusInfo
)
/*++
Routine Description:
This routine is invoked to bind/unbind, enable/disable an interface
Arguments:
Index - the interface to be bound
InterfaceActive - whether the interface is active
StatusType - type of status being changed (bind or enabled)
StatusInfo - Info pertaining to the state being changed
Return Value:
ULONG - Win32 Status code
Environment:
The routine runs in the context of an IP router-manager thread.
--*/
{
ULONG Error = NO_ERROR;
switch(StatusType) {
case RIS_INTERFACE_ADDRESS_CHANGE: {
PIP_ADAPTER_BINDING_INFO BindInfo =
(PIP_ADAPTER_BINDING_INFO)StatusInfo;
if (BindInfo->AddressCount) {
Error = H323RmBindInterface(Index, StatusInfo);
} else {
Error = H323RmUnbindInterface(Index);
}
break;
}
case RIS_INTERFACE_ENABLED: {
Error = H323RmEnableInterface(Index);
break;
}
case RIS_INTERFACE_DISABLED: {
Error = H323RmDisableInterface(Index);
break;
}
}
return Error;
} // H323RmInterfaceStatus
ULONG
H323RmBindInterface(
ULONG Index,
PVOID BindingInfo
)
/*++
Routine Description:
This routine is invoked to bind an interface to its IP address(es).
Arguments:
Index - the interface to be bound
BindingInfo - the addressing information
Return Value:
ULONG - Win32 status code.
Environment:
The routine runs in the context of an IP router-manager thread.
--*/
{
ULONG Error;
PROFILE("H323RmBindInterface");
REFERENCE_H323_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
Error =
H323BindInterface(
Index,
(PIP_ADAPTER_BINDING_INFO)BindingInfo
);
DEREFERENCE_H323_AND_RETURN(Error);
} // H323RmBindInterface
ULONG
H323RmUnbindInterface(
ULONG Index
)
/*++
Routine Description:
This routine is invoked to unbind an interface from its IP address(es).
Arguments:
Index - the interface to be unbound
Return Value:
ULONG - Win32 status code.
Environment:
The routine runs in the context of an IP router-manager thread.
--*/
{
ULONG Error;
PROFILE("H323RmUnbindInterface");
REFERENCE_H323_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
Error =
H323UnbindInterface(
Index
);
DEREFERENCE_H323_AND_RETURN(Error);
} // H323RmUnbindInterface
ULONG
H323RmEnableInterface(
ULONG Index
)
/*++
Routine Description:
This routine is invoked to enable operation on an interface.
Arguments:
Index - the interface to be enabled.
Return Value:
ULONG - Win32 status code.
Environment:
The routine runs in the context of an IP router-manager thread.
--*/
{
ULONG Error;
PROFILE("H323RmEnableInterface");
REFERENCE_H323_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
Error =
H323EnableInterface(
Index
);
DEREFERENCE_H323_AND_RETURN(Error);
} // H323RmEnableInterface
ULONG
H323RmDisableInterface(
ULONG Index
)
/*++
Routine Description:
This routine is invoked to disable operation on an interface.
Arguments:
Index - the interface to be disabled.
Return Value:
ULONG - Win32 status code.
Environment:
The routine runs in the context of an IP router-manager thread.
--*/
{
ULONG Error;
PROFILE("H323RmDisableInterface");
REFERENCE_H323_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
Error =
H323DisableInterface(
Index
);
DEREFERENCE_H323_AND_RETURN(Error);
} // H323RmDisableInterface
ULONG
APIENTRY
H323RmGetGlobalInfo(
PVOID GlobalInfo,
IN OUT PULONG GlobalInfoSize,
IN OUT PULONG StructureVersion,
IN OUT PULONG StructureSize,
IN OUT PULONG StructureCount
)
/*++
Routine Description:
This routine is invoked to retrieve the configuration for the component.
Arguments:
GlobalInfo - receives the configuration
GlobalInfoSize - receives the size of the configuration
Return Value:
ULONG - Win32 status code
Environment:
The routine runs in the context of an IP router-manager thread.
--*/
{
ULONG Size;
PROFILE("H323RmGetGlobalInfo");
REFERENCE_H323_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
if (!GlobalInfoSize || (*GlobalInfoSize && !GlobalInfo)) {
DEREFERENCE_H323_AND_RETURN(ERROR_INVALID_PARAMETER);
}
EnterCriticalSection(&H323GlobalInfoLock);
Size = sizeof(*H323GlobalInfo);
if (*GlobalInfoSize < Size) {
LeaveCriticalSection(&H323GlobalInfoLock);
*StructureSize = *GlobalInfoSize = Size;
if (StructureCount) {*StructureCount = 1;}
DEREFERENCE_H323_AND_RETURN(ERROR_INSUFFICIENT_BUFFER);
}
CopyMemory(GlobalInfo, H323GlobalInfo, Size);
LeaveCriticalSection(&H323GlobalInfoLock);
*StructureSize = *GlobalInfoSize = Size;
if (StructureCount) {*StructureCount = 1;}
DEREFERENCE_H323_AND_RETURN(NO_ERROR);
} // H323RmGetGlobalInfo
ULONG
APIENTRY
H323RmSetGlobalInfo(
PVOID GlobalInfo,
ULONG StructureVersion,
ULONG StructureSize,
ULONG StructureCount
)
/*++
Routine Description:
This routine is invoked to change the configuration for the component.
Arguments:
GlobalInfo - the new configuration
Return Value:
ULONG - Win32 status code
Environment:
The routine runs in the context of an IP router-manager thread.
--*/
{
ULONG OldFlags;
ULONG NewFlags;
PIP_H323_GLOBAL_INFO NewInfo;
ULONG Size;
PROFILE("H323RmSetGlobalInfo");
REFERENCE_H323_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
if (!GlobalInfo) { DEREFERENCE_H323_AND_RETURN(ERROR_INVALID_PARAMETER); }
Size = sizeof(*H323GlobalInfo);
NewInfo = reinterpret_cast<PIP_H323_GLOBAL_INFO>(NH_ALLOCATE(Size));
if (!NewInfo) {
NhTrace(
TRACE_FLAG_INIT,
"H323RmSetGlobalInfo: error reallocating global info"
);
NhErrorLog(
IP_H323_LOG_ALLOCATION_FAILED,
0,
"%d",
Size
);
DEREFERENCE_H323_AND_RETURN(ERROR_NOT_ENOUGH_MEMORY);
}
CopyMemory(NewInfo, GlobalInfo, Size);
EnterCriticalSection(&H323GlobalInfoLock);
OldFlags = H323GlobalInfo->Flags;
NH_FREE(H323GlobalInfo);
H323GlobalInfo = NewInfo;
NewFlags = H323GlobalInfo->Flags;
LeaveCriticalSection(&H323GlobalInfoLock);
DEREFERENCE_H323_AND_RETURN(NO_ERROR);
} // H323RmSetGlobalInfo
ULONG
APIENTRY
H323RmMibCreate(
ULONG InputDataSize,
PVOID InputData
)
{
return ERROR_NOT_SUPPORTED;
}
ULONG
APIENTRY
H323RmMibDelete(
ULONG InputDataSize,
PVOID InputData
)
{
return ERROR_NOT_SUPPORTED;
}
ULONG
APIENTRY
H323RmMibGet(
ULONG InputDataSize,
PVOID InputData,
OUT PULONG OutputDataSize,
OUT PVOID OutputData
)
/*++
Routine Description:
The transparent proxy only exposes one item to the MIB; its statistics.
Arguments:
InputDataSize - the MIB query data size
InputData - specifies the MIB object to be retrieved
OutputDataSize - the MIB response data size
OutputData - receives the MIB object retrieved
Return Value:
ULONG - Win32 status code.
--*/
{
ULONG Error;
PIP_H323_MIB_QUERY Oidp;
PROFILE("H323RmMibGet");
REFERENCE_H323_OR_RETURN(ERROR_CAN_NOT_COMPLETE);
if (InputDataSize < sizeof(*Oidp) || !OutputDataSize) {
Error = ERROR_INVALID_PARAMETER;
} else {
Oidp = (PIP_H323_MIB_QUERY)InputData;
// switch(Oidp->Oid) {
// default: {
NhTrace(
TRACE_FLAG_H323,
"H323RmMibGet: oid %d invalid",
Oidp->Oid
);
Error = ERROR_INVALID_PARAMETER;
// break;
// }
// }
}
DEREFERENCE_H323_AND_RETURN(Error);
}
ULONG
APIENTRY
H323RmMibSet(
ULONG InputDataSize,
PVOID InputData
)
{
return ERROR_NOT_SUPPORTED;
}
ULONG
APIENTRY
H323RmMibGetFirst(
ULONG InputDataSize,
PVOID InputData,
OUT PULONG OutputDataSize,
OUT PVOID OutputData
)
{
return ERROR_NOT_SUPPORTED;
}
ULONG
APIENTRY
H323RmMibGetNext(
ULONG InputDataSize,
PVOID InputData,
OUT PULONG OutputDataSize,
OUT PVOID OutputData
)
{
return ERROR_NOT_SUPPORTED;
}