Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1003 lines
31 KiB

#include "precomp.h"
DEBUG_FILEZONE(ZONE_T120_T123PSTN);
/* SCF.cpp
*
* Copyright (c) 1994-1995 by DataBeam Corporation, Lexington, KY
*
* Abstract:
* This is the implementation file for the CLayerSCF class
*
* Private Instance Variables:
* Remote_Call_Reference - List of active SCFCalls initiated by the
* remote site
* Call_Reference - List of active SCFCalls initiated locally
* DLCI_List - This list matches DLCIs to SCFCalls, its
* only real purpose is for DisconnectRequest()
* Message_List - List of OwnerCallback messages that can't
* be processed immediately.
* m_pT123 - Address of owner object
* m_pQ922 - Address of lower layer
* m_nMsgBase - Message base passed in by owner. Used in
* OwnerCallback
* Identifier - Identifier passed to lower layer
* Link_Originator - TRUE if we initiated the connection
* Maximum_Packet_Size - Maximum packet size transmittable
* DataLink_Struct - Address of structure holding DataLink parms
* Data_Request_Memory_Manager - Address of memory manager
* Lower_Layer_Prepend - Holds number of bytes prepended to packet
* by the lower layer
* Lower_Layer_Append - Holds number of bytes appended to packet by
* the lower layer
* Call_Reference_Base - This value holds the next call reference
* number.
*
* Caveats:
* None.
*
* Authors:
* James W. Lawwill
*/
#include "scf.h"
/*
* CLayerSCF::CLayerSCF (
* PTransportResources transport_resources,
* IObject * owner_object,
* IProtocolLayer * lower_layer,
* USHORT message_base,
* USHORT identifier,
* BOOL link_originator,
* PChar config_file)
*
* Public
*
* Functional Description:
* This is the CLayerSCF constructor. This routine initializes all
* variables and allocates buffer space.
*/
CLayerSCF::CLayerSCF
(
T123 *owner_object,
CLayerQ922 *pQ922, // lower layer
USHORT message_base,
USHORT identifier,
BOOL link_originator,
PDataLinkParameters datalink_struct,
PMemoryManager data_request_memory_manager,
BOOL * initialized
)
:
Remote_Call_Reference (TRANSPORT_HASHING_BUCKETS),
Call_Reference (TRANSPORT_HASHING_BUCKETS),
DLCI_List (TRANSPORT_HASHING_BUCKETS),
m_pT123(owner_object),
m_nMsgBase(message_base),
m_pQ922(pQ922)
{
ProtocolLayerError error;
TRACE_OUT(("CLayerSCF::CLayerSCF"));
Link_Originator = (USHORT)link_originator;
Identifier = identifier;
Data_Request_Memory_Manager = data_request_memory_manager;
Call_Reference_Base = 1;
*initialized = TRUE;
/*
** Fill in the DataLink_Struct with the proposed values and the default
** values
*/
DataLink_Struct.k_factor = datalink_struct -> k_factor;
DataLink_Struct.default_k_factor = datalink_struct -> default_k_factor;
DataLink_Struct.n201 = datalink_struct -> n201;
DataLink_Struct.default_n201 = datalink_struct -> default_n201;
DataLink_Struct.t200 = datalink_struct -> t200;
DataLink_Struct.default_t200 = datalink_struct -> default_t200;
/*
** Find the maximum packet size
*/
m_pQ922->GetParameters(
&Maximum_Packet_Size,
&Lower_Layer_Prepend,
&Lower_Layer_Append);
/*
** Register with the lower layer
*/
error = m_pQ922->RegisterHigherLayer(
Identifier,
Data_Request_Memory_Manager,
(IProtocolLayer *) this);
if (error != PROTOCOL_LAYER_NO_ERROR)
{
ERROR_OUT(("Multiplexer: constructor: Error registering with lower layer"));
*initialized = FALSE;
}
}
/*
* CLayerSCF::~CLayerSCF (void)
*
* Public
*
* Functional Description:
* This is the CLayerSCF destructor. This routine cleans up everything.
*/
CLayerSCF::~CLayerSCF (void)
{
TRACE_OUT(("CLayerSCF::~CLayerSCF"));
PMessageStruct message;
PSCFCall lpSCFCall;
m_pQ922->RemoveHigherLayer(Identifier);
/*
** Delete all locally initiated calls
*/
Call_Reference.reset();
while (Call_Reference.iterate ((PDWORD_PTR) &lpSCFCall))
{
delete lpSCFCall;
}
/*
** Delete all remotely initiated calls
*/
Remote_Call_Reference.reset();
while (Remote_Call_Reference.iterate ((PDWORD_PTR) &lpSCFCall))
{
delete lpSCFCall;
}
/*
** Delete all passive owner callbacks
*/
Message_List.reset();
while (Message_List.iterate ((PDWORD_PTR) &message))
{
delete message;
}
}
/*
* CLayerSCF::ConnectRequest (
* DLCI dlci,
* TransportPriority priority)
*
* Public
*
* Functional Description:
* This function initiates a connection with the remote site. As a result,
* we will create a SCFCall and tell it to initiate a connection.
*/
SCFError CLayerSCF::ConnectRequest (
DLCI dlci,
TransportPriority priority)
{
TRACE_OUT(("CLayerSCF::ConnectRequest"));
BOOL initialized;
CallReference call_reference;
SCFError return_value = SCF_NO_ERROR;
PSCFCall lpSCFCall;
/*
** Get the next valid local call reference value.
*/
call_reference = GetNextCallReference ();
if (call_reference == 0)
return (SCF_CONNECTION_FULL);
/*
** Create an SCFCall object to handle this call reference
*/
DBG_SAVE_FILE_LINE
lpSCFCall= new SCFCall(this,
m_pQ922,
call_reference << 8,
&DataLink_Struct,
Data_Request_Memory_Manager,
&initialized);
if (lpSCFCall != NULL)
{
if (initialized)
{
Call_Reference.insert ((DWORD_PTR) call_reference, (DWORD_PTR) lpSCFCall);
/*
** Register the DLCI and the call reference
*/
DLCI_List.insert ((DWORD_PTR) dlci, (DWORD_PTR) lpSCFCall);
lpSCFCall->ConnectRequest (call_reference, dlci, priority);
}
else
{
delete lpSCFCall;
return_value = SCF_MEMORY_ALLOCATION_ERROR;
}
}
else
{
return_value = SCF_MEMORY_ALLOCATION_ERROR;
}
return (return_value);
}
/*
* CLayerSCF::ConnectResponse (
* CallReference call_reference,
* DLCI dlci,
* BOOL valid_dlci)
*
* Public
*
* Functional Description:
* This is the CLayerSCF destructor. This routine cleans up everything.
*/
SCFError CLayerSCF::ConnectResponse (
CallReference call_reference,
DLCI dlci,
BOOL valid_dlci)
{
TRACE_OUT(("CLayerSCF::ConnectResponse"));
PSCFCall lpSCFCall = NULL;
if (valid_dlci)
{
if (Remote_Call_Reference.find ((DWORD_PTR) call_reference, (PDWORD_PTR) &lpSCFCall))
DLCI_List.insert ((DWORD_PTR) dlci, (DWORD_PTR) lpSCFCall);
}
if(NULL != lpSCFCall)
{
lpSCFCall->ConnectResponse (valid_dlci);
return (SCF_NO_ERROR);
}
return (SCF_NO_SUCH_DLCI);
}
/*
* SCFError CLayerSCF::DisconnectRequest (
* DLCI dlci)
*
* Public
*
* Functional Description:
* This function calls the SCFCall associated with the DLCI and starts
* the disconnect operation
*/
SCFError CLayerSCF::DisconnectRequest (
DLCI dlci)
{
TRACE_OUT(("CLayerSCF::DisconnectRequest"));
PSCFCall lpSCFCall;
if (DLCI_List.find ((DWORD_PTR) dlci, (PDWORD_PTR) &lpSCFCall) == FALSE)
return (SCF_NO_SUCH_DLCI);
lpSCFCall->DisconnectRequest ();
return (SCF_NO_ERROR);
}
/*
* SCFError CLayerSCF::DataIndication (
* LPBYTE packet_address,
* ULONG buffer_size,
* PULong packet_length)
*
* Public
*
* Functional Description:
* This function is called by the lower layer when it has received a
* packet for us to process.
*/
ProtocolLayerError CLayerSCF::DataIndication (
LPBYTE packet_address,
ULONG packet_length,
PULong bytes_accepted)
{
TRACE_OUT(("CLayerSCF::DataIndication"));
BOOL legal_packet;
CallReference call_reference;
USHORT length_call_reference;
USHORT message_type;
PSCFCall call;
USHORT remainder_length;
USHORT local;
BOOL initialized;
remainder_length = (USHORT) packet_length;
*bytes_accepted = packet_length;
if (*(packet_address+PROTOCOL_DISCRIMINATOR) != Q931_PROTOCOL_DISCRIMINATOR)
return (PROTOCOL_LAYER_NO_ERROR);
/*
** Get the call reference value
*/
call_reference = *(packet_address + CALL_REFERENCE_VALUE);
if (call_reference == 0)
{
ERROR_OUT(("CLayerSCF: DataIndication: illegal call reference value = 0"));
return (PROTOCOL_LAYER_NO_ERROR);
}
length_call_reference = *(packet_address + LENGTH_CALL_REFERENCE);
packet_address += CALL_REFERENCE_VALUE + length_call_reference;
remainder_length -= (CALL_REFERENCE_VALUE + length_call_reference);
/*
** Get the message type
*/
message_type = *(packet_address++);
remainder_length--;
switch (message_type)
{
case SETUP:
/*
** If the call reference is already active, return error
*/
if (Remote_Call_Reference.find ((DWORD) call_reference))
{
TRACE_OUT(("CLayerSCF: DataIndication: SETUP: call reference is already active"));
break;
}
if ((call_reference & CALL_REFERENCE_ORIGINATOR) == 1)
{
TRACE_OUT(("CLayerSCF: DataIndication: SETUP: call reference Originator bit is set incorrectly"));
break;
}
/*
** This is a new call reference, create a new SCFCall to handle
** the call. Since the remote site initiated the call, put this
** reference in the Remote array
*/
call= new SCFCall(this,
m_pQ922,
(call_reference << 8),
&DataLink_Struct,
Data_Request_Memory_Manager,
&initialized);
if (call != NULL)
{
if (initialized)
{
Remote_Call_Reference.insert ((DWORD_PTR) call_reference, (DWORD_PTR) call);
/*
** Allow the call to process the SETUP command
*/
legal_packet = call->ProcessSetup (call_reference, packet_address, remainder_length);
/*
** If the packet was illegal, remove the reference
*/
if (legal_packet == FALSE) {
delete call;
Remote_Call_Reference.remove ((DWORD) call_reference);
}
}
else
{
delete call;
}
}
break;
case CONNECT:
/*
** The call originator bit must be set to signify that we are
** the originators of the call
*/
if ((call_reference & CALL_REFERENCE_ORIGINATOR) == 0)
{
TRACE_OUT(("CLayerSCF: DataIndication: CONNECT: call reference Originator bit is set incorrectly"));
break;
}
/*
** If the call reference is not already active, return error
*/
call_reference &= CALL_ORIGINATOR_MASK;
if (Call_Reference.find ((DWORD_PTR) call_reference, (PDWORD_PTR) &call) == FALSE)
{
TRACE_OUT(("CLayerSCF: DataIndication: CONNECT: call reference is not already active = %x", call_reference));
break;
}
call->ProcessConnect (packet_address, remainder_length);
break;
case CONNECT_ACKNOWLEDGE:
/*
** If the call reference is already active, return error
*/
if (Remote_Call_Reference.find ((DWORD_PTR) call_reference, (PDWORD_PTR) &call) == FALSE)
{
TRACE_OUT(("CLayerSCF: DataIndication: CONNECT_ACK: call reference is not active"));
break;
}
/*
** The call originator bit should NOT be set
*/
if ((call_reference & CALL_REFERENCE_ORIGINATOR) == 1)
{
TRACE_OUT(("CLayerSCF: DataIndication: CONNECT_ACK: call reference Originator bit is set incorrectly"));
break;
}
call->ProcessConnectAcknowledge (packet_address, remainder_length);
break;
case RELEASE_COMPLETE:
local = call_reference & CALL_REFERENCE_ORIGINATOR;
call_reference &= CALL_ORIGINATOR_MASK;
/*
** If the call is local, check the Call_Reference list for validity
*/
if (local)
{
if (Call_Reference.find ((DWORD_PTR) call_reference, (PDWORD_PTR) &call) == FALSE)
{
TRACE_OUT(("CLayerSCF: DataIndication: RELEASE_COMPLETE: call reference is not already active"));
break;
}
}
else
{
/*
** If the call is remote, check the Call_Reference list for
** validity
*/
if (Remote_Call_Reference.find ((DWORD_PTR) call_reference, (PDWORD_PTR) &call) == FALSE)
{
TRACE_OUT(("CLayerSCF: DataIndication: RELEASE_COMPLETE: call reference is not already active"));
break;
}
}
call -> ProcessReleaseComplete (packet_address, remainder_length);
ProcessMessages ();
break;
case DISCONNECT:
case RELEASE:
case STATUS:
case STATUS_ENQUIRY:
TRACE_OUT(("CLayerSCF:DataIndication: Illegal command received = %x", message_type));
local = call_reference & CALL_REFERENCE_ORIGINATOR;
call_reference &= CALL_ORIGINATOR_MASK;
/*
** If the call is local, check the Call_Reference list for validity
*/
if (local)
{
if (Call_Reference.find ((DWORD_PTR) call_reference, (PDWORD_PTR) &call) == FALSE)
break;
}
else
{
/*
** If the call is remote, check the Call_Reference list for
** validity
*/
if (Remote_Call_Reference.find ((DWORD_PTR) call_reference, (PDWORD_PTR) &call) == FALSE)
break;
}
call -> DisconnectRequest ();
break;
default:
ERROR_OUT(("CLayerSCF:DataIndication: Unrecognized command received = %x", message_type));
break;
}
return (PROTOCOL_LAYER_NO_ERROR);
}
/*
* ProtocolLayerError CLayerSCF::PollTransmitter (
* ULONG,
* USHORT data_to_transmit,
* USHORT * pending_data,
* USHORT *)
*
* Public
*
* Functional Description:
* This function should be called frequently to allow the SCF calls to
* transmit packets.
*/
ProtocolLayerError CLayerSCF::PollTransmitter (
ULONG_PTR,
USHORT data_to_transmit,
USHORT * pending_data,
USHORT *)
{
// TRACE_OUT(("CLayerSCF::PollTransmitter"));
USHORT local_pending_data;
PSCFCall lpSCFCall;
*pending_data = 0;
/*
** Go through each of the locally originated calls and attempt to transmit
** data.
*/
Call_Reference.reset();
while (Call_Reference.iterate ((PDWORD_PTR) &lpSCFCall))
{
lpSCFCall->PollTransmitter (data_to_transmit, &local_pending_data);
*pending_data |= local_pending_data;
}
/*
** Go through each of the remotely originated calls and attempt to transmit
** data.
*/
Remote_Call_Reference.reset();
while (Remote_Call_Reference.iterate ((PDWORD_PTR) &lpSCFCall))
{
lpSCFCall-> PollTransmitter (data_to_transmit, &local_pending_data);
*pending_data |= local_pending_data;
}
ProcessMessages ();
return (PROTOCOL_LAYER_NO_ERROR);
}
/*
* SCFError CLayerSCF::DataRequest (
* ULONG,
* LPBYTE,
* ULONG,
* PULong)
*
* Public
*
* Functional Description:
* This function can not be called. This layer does not permit data
* requests from higher layers.
*/
ProtocolLayerError CLayerSCF::DataRequest (
ULONG_PTR,
LPBYTE,
ULONG,
PULong)
{
return (PROTOCOL_LAYER_ERROR);
}
/*
* SCFError CLayerSCF::DataRequest (
* ULONG,
* PMemory,
* USHORT *)
*
* Public
*
* Functional Description:
* This function can not be called. This layer does not permit data
* requests from higher layers.
*/
ProtocolLayerError CLayerSCF::DataRequest (
ULONG_PTR,
PMemory,
PULong)
{
return (PROTOCOL_LAYER_ERROR);
}
/*
* void CLayerSCF::PollReceiver (
* ULONG)
*
* Public
*
* Functional Description
* This function only checks its passive callback list. If this function
* had a higher layer that it was passing data too, it would do that. But
* since it has no higher layer, it doesn't do much.
*/
ProtocolLayerError CLayerSCF::PollReceiver(void)
{
ProcessMessages ();
return (PROTOCOL_LAYER_NO_ERROR);
}
/*
* CallReference CLayerSCF::GetNextCallReference ()
*
* Functional Description
* This function searches the local call reference list for a valid call
* reference number. If it can not find one, it returns 0. Valid call
* references are 1-127.
*
* Formal Parameters
* None
*
* Return Value
* Call reference value
*
* Side Effects
* None
*
* Caveats
* None
*/
USHORT CLayerSCF::GetNextCallReference ()
{
USHORT call_reference;
if (Call_Reference.entries() == 127)
return (0);
call_reference = Call_Reference_Base;
Call_Reference_Base++;
if (Call_Reference_Base == 128)
Call_Reference_Base = 1;
while (Call_Reference.find ((DWORD) call_reference))
{
call_reference++;
if (call_reference == 128)
call_reference = 1;
}
return (call_reference);
}
/*
* ULONG CLayerSCF::OwnerCallback (
* USHORT message,
* ULONG parameter1,
* ULONG parameter2,
* PVoid parameter3)
*
* Functional Description
* This function is called by the SCFCall objects when they need to
* communicate a message to us. If the message can not be processed
* immediately, it is saved in a message structure and processed at a
* later time.
*
* Formal Parameters
* None
*
* Return Value
* Message dependent
*
* Side Effects
* None
*
* Caveats
* None
*/
ULONG CLayerSCF::OwnerCallback
(
ULONG message,
void *parameter1,
void *parameter2,
void *parameter3
)
{
TRACE_OUT(("CLayerSCF::OwnerCallback"));
ULONG actual_message;
CallReference call_reference;
PMessageStruct passive_message;
PNetworkConnectStruct connect_struct;
PSCFCall lpSCFCall;
/*
** The upper byte of the message is the call reference message that it
** represents
*/
call_reference = (CallReference) (message >> 8);
actual_message = message & 0xff;
switch (actual_message)
{
case NETWORK_CONNECT_CONFIRM:
/*
** A CONNECT_CONFIRM message is returned by the SCFCall when a call
** that we originated, has been established. We register the
** SCFCall with the DLCI and call the owner object.
*/
connect_struct = (PNetworkConnectStruct) parameter3;
connect_struct -> call_reference = call_reference;
if (Call_Reference.find ((DWORD_PTR) call_reference, (PDWORD_PTR) &lpSCFCall))
{
DLCI_List.insert ((DWORD_PTR) connect_struct->dlci, (DWORD_PTR) lpSCFCall);
}
m_pT123->OwnerCallback(m_nMsgBase + actual_message, 0, 0, parameter3);
break;
case NETWORK_CONNECT_INDICATION:
/*
** A CONNECT_INDICATION message is returned by the SCFCall when the
** remote SCF wants to create a new call. We will call the owner
** of this object to see if he will accept the DLCI requested.
*/
connect_struct = (PNetworkConnectStruct) parameter3;
connect_struct -> call_reference = call_reference;
m_pT123->OwnerCallback(m_nMsgBase + actual_message, 0, 0, parameter3);
break;
case NETWORK_DISCONNECT_INDICATION:
/*
** This message is received from the SCFCall when one side wants
** to terminate the call. We treat this message differently than
** the other messages because it involves the deletion of an
** SCFCall object. Don't forget, if we delete the object and then
** return to it at the end of this procedure, a GPF could occur.
*/
DBG_SAVE_FILE_LINE
passive_message = new MessageStruct;
if (NULL != passive_message)
{
passive_message -> message = message;
passive_message -> parameter1 = parameter1;
passive_message -> parameter2 = parameter2;
passive_message -> parameter3 = parameter3;
Message_List.append ((DWORD_PTR) passive_message);
}
else
{
ERROR_OUT(("CLayerSCF::OwnerCallback: cannot allocate MessageStruct"));
}
break;
default:
ERROR_OUT(("CLayerSCF: Illegal message: %x", actual_message));
break;
}
return (0);
}
/*
* ProtocolLayerError CLayerSCF::GetParameters (
* USHORT,
* USHORT *,
* USHORT *,
* USHORT *)
*
* Public
*
* Functional Description
* This function is not valid in this layer. It must exist because this
* class inherits from inherits from ProtocolLayer and it is a pure virtual
* function.
*/
ProtocolLayerError CLayerSCF::GetParameters (
USHORT *,
USHORT *,
USHORT *)
{
return (PROTOCOL_LAYER_REGISTRATION_ERROR);
}
/*
* ProtocolLayerError CLayerSCF::RegisterHigherLayer (
* USHORT,
* PMemoryManager,
* IProtocolLayer *)
*
* Public
*
* Functional Description
* This function is not valid in this layer. It must exist because this
* class inherits from inherits from ProtocolLayer and it is a pure virtual
* function.
*/
ProtocolLayerError CLayerSCF::RegisterHigherLayer (
ULONG_PTR,
PMemoryManager,
IProtocolLayer *)
{
return (PROTOCOL_LAYER_REGISTRATION_ERROR);
}
/*
* ProtocolLayerError CLayerSCF::RemoveHigherLayer (
* USHORT)
*
* Public
*
* Functional Description
* This function is not valid in this layer. It must exist because this
* class inherits from inherits from ProtocolLayer and it is a pure virtual
* function.
*/
ProtocolLayerError CLayerSCF::RemoveHigherLayer (
ULONG_PTR)
{
return (PROTOCOL_LAYER_REGISTRATION_ERROR);
}
/*
* void CLayerSCF::ProcessMessages ()
*
* Functional Description
* This function is called periodically to check its passive messages.
* Passive messages occur when the SCF gets a callback but can't process
* it immediately. Therefore, it puts the message and its parameters in
* a structure and saves the message for later.
*
* Formal Parameters
* None
*
* Return Value
* Message dependent
*
* Side Effects
* None
*
* Caveats
* None
*/
void CLayerSCF::ProcessMessages ()
{
// TRACE_OUT(("CLayerSCF::ProcessMessages"));
PMessageStruct message;
CallReference call_reference;
ULONG actual_message;
USHORT call_originator;
USHORT cause;
DLCI dlci;
BOOL call_reference_valid;
void *parameter1;
void *parameter2;
PSCFCall lpSCFCall;
/*
** Go thru each message in the list
*/
while (Message_List.isEmpty() == FALSE)
{
/*
** Remote the first message from the list
*/
message = (PMessageStruct) Message_List.get ();
call_reference = (CallReference) ((message -> message) >> 8);
actual_message = (message -> message) & 0xff;
parameter1 = message -> parameter1;
parameter2 = message -> parameter2;
switch (actual_message)
{
case NETWORK_DISCONNECT_INDICATION:
/*
** This message is received from the SCFCall when one side
** wants to terminate the call. We treat this message
** differently than the other messages because it involves the
** deletion of an SCFCall object.
*/
dlci = (DLCI) parameter1;
call_originator = (USHORT) (((ULONG_PTR) parameter2) >> 16);
cause = (USHORT) ((ULONG_PTR) parameter2) & 0xffff;
/*
** dlci is 0 if the SCFCall was never assigned a DLCI by the
** remote site.
*/
if (dlci != 0)
DLCI_List.remove ((DWORD) dlci);
/*
** If the SCFCall was the call originator, its reference is
** in Call_Reference, otherwise it is in Remote_Call_Reference.
**
** Check the Call_Reference list to make sure that the
** call_reference is valid. The way passive owner callbacks
** work, it is possible to receive a DISCONNECT for a callback
** that was already disconnected.
*/
call_reference_valid = FALSE;
if (call_originator)
{
if (Call_Reference.find ((DWORD_PTR) call_reference, (PDWORD_PTR) &lpSCFCall))
{
delete lpSCFCall;
Call_Reference.remove ((DWORD) call_reference);
call_reference_valid = TRUE;
}
}
else
{
if (Remote_Call_Reference.find ((DWORD_PTR) call_reference, (PDWORD_PTR) &lpSCFCall))
{
delete lpSCFCall;
Remote_Call_Reference.remove ((DWORD_PTR) call_reference);
call_reference_valid = TRUE;
}
}
if (call_reference_valid)
{
/*
** If the cause of the disconnect was because the Requested
** channel was unavailable, we will tell the owner of this
** layer to retry the connection.
*/
if (cause == REQUESTED_CHANNEL_UNAVAILABLE)
{
parameter2 = (void *) ((((ULONG_PTR) call_originator) << 16) | TRUE);
}
else
{
parameter2 = (void *) ((((ULONG_PTR) call_originator) << 16) | FALSE);
}
/*
** Let the owner of this object know that a disconnect has
** occured.
*/
m_pT123->OwnerCallback(m_nMsgBase + NETWORK_DISCONNECT_INDICATION,
parameter1, parameter2);
}
break;
}
/*
** Delete the message structure
*/
delete message;
}
}