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.
468 lines
15 KiB
468 lines
15 KiB
/*==========================================================================
|
|
*
|
|
* Copyright (C) 1998-2000 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: Endpoint.h
|
|
* Content: DNSerial communications endpoint
|
|
*
|
|
*
|
|
* History:
|
|
* Date By Reason
|
|
* ==== == ======
|
|
* 01/20/99 jtk Created
|
|
* 05/11/99 jtk Split out to make a base class
|
|
***************************************************************************/
|
|
|
|
#ifndef __ENDPOINT_H__
|
|
#define __ENDPOINT_H__
|
|
|
|
//**********************************************************************
|
|
// Constant definitions
|
|
//**********************************************************************
|
|
|
|
#define MAX_PHONE_NUMBER_SIZE 200
|
|
|
|
//
|
|
// enumeration of endpoint types
|
|
//
|
|
typedef enum _ENDPOINT_TYPE
|
|
{
|
|
ENDPOINT_TYPE_UNKNOWN = 0, // unknown endpoint type
|
|
ENDPOINT_TYPE_LISTEN, // 'Listen' endpoint
|
|
ENDPOINT_TYPE_CONNECT, // 'Conenct' endpoint
|
|
ENDPOINT_TYPE_ENUM, // 'Enum' endpoint
|
|
ENDPOINT_TYPE_CONNECT_ON_LISTEN // endpoint connected from a 'listen'
|
|
} ENDPOINT_TYPE;
|
|
|
|
//
|
|
// enumeration of the states an endpoint can be in
|
|
//
|
|
typedef enum
|
|
{
|
|
ENDPOINT_STATE_UNINITIALIZED = 0, // uninitialized state
|
|
ENDPOINT_STATE_ATTEMPTING_ENUM, // attempting to enum
|
|
ENDPOINT_STATE_ENUM, // endpoint is supposed to enum connections
|
|
ENDPOINT_STATE_ATTEMPTING_CONNECT, // attempting to connect
|
|
ENDPOINT_STATE_CONNECT_CONNECTED, // endpoint is supposed to connect and is connected
|
|
ENDPOINT_STATE_ATTEMPTING_LISTEN, // attempting to listen
|
|
ENDPOINT_STATE_LISTENING, // endpoint is supposed to listen and is listening
|
|
ENDPOINT_STATE_DISCONNECTING, // endpoint is disconnecting
|
|
|
|
ENDPOINT_STATE_MAX
|
|
} ENDPOINT_STATE;
|
|
|
|
//**********************************************************************
|
|
// Macro definitions
|
|
//**********************************************************************
|
|
|
|
//**********************************************************************
|
|
// Structure definitions
|
|
//**********************************************************************
|
|
|
|
//
|
|
// forward structure references
|
|
//
|
|
typedef struct _JOB_HEADER JOB_HEADER;
|
|
typedef struct _THREAD_POOL_JOB THREAD_POOL_JOB;
|
|
class CModemCommandData;
|
|
class CDataPort;
|
|
class CModemReadIOData;
|
|
class CModemThreadPool;
|
|
class CModemWriteIOData;
|
|
|
|
//
|
|
// structure used to get data from the endpoint port pool
|
|
//
|
|
typedef struct _ENDPOINT_POOL_CONTEXT
|
|
{
|
|
CModemSPData *pSPData;
|
|
BOOL fModem;
|
|
} ENDPOINT_POOL_CONTEXT;
|
|
|
|
//
|
|
// structure to bind extra information to an enum query to be used on enum reponse
|
|
//
|
|
typedef struct _ENDPOINT_ENUM_QUERY_CONTEXT
|
|
{
|
|
SPIE_QUERY EnumQueryData;
|
|
HANDLE hEndpoint;
|
|
UINT_PTR uEnumRTTIndex;
|
|
} ENDPOINT_ENUM_QUERY_CONTEXT;
|
|
|
|
//**********************************************************************
|
|
// Variable definitions
|
|
//**********************************************************************
|
|
|
|
//**********************************************************************
|
|
// Function prototypes
|
|
//**********************************************************************
|
|
|
|
//**********************************************************************
|
|
// Class definition
|
|
//**********************************************************************
|
|
|
|
class CModemEndpoint
|
|
{
|
|
public:
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CModemEndpoint::Lock"
|
|
void Lock( void )
|
|
{
|
|
DNASSERT( m_Flags.fInitialized != FALSE );
|
|
DNEnterCriticalSection( &m_Lock );
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CModemEndpoint::Unlock"
|
|
void Unlock( void )
|
|
{
|
|
DNASSERT( m_Flags.fInitialized != FALSE );
|
|
DNLeaveCriticalSection( &m_Lock );
|
|
}
|
|
|
|
void ReturnSelfToPool( void );
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CModemEndpoint::AddRef"
|
|
void AddRef( void )
|
|
{
|
|
DNASSERT( m_iRefCount != 0 );
|
|
DNInterlockedIncrement( &m_iRefCount );
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CModemEndpoint::DecRef"
|
|
void DecRef( void )
|
|
{
|
|
DNASSERT( m_iRefCount != 0 );
|
|
if ( DNInterlockedDecrement( &m_iRefCount ) == 0 )
|
|
{
|
|
ReturnSelfToPool();
|
|
}
|
|
}
|
|
|
|
void AddCommandRef( void )
|
|
{
|
|
DNInterlockedIncrement( &m_lCommandRefCount );
|
|
AddRef();
|
|
}
|
|
|
|
void DecCommandRef( void )
|
|
{
|
|
if ( DNInterlockedDecrement( &m_lCommandRefCount ) == 0 )
|
|
{
|
|
CleanUpCommand();
|
|
}
|
|
DecRef();
|
|
}
|
|
|
|
DPNHANDLE GetHandle( void ) const { return m_Handle; }
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CModemEndpoint::SetHandle"
|
|
void SetHandle( const DPNHANDLE Handle )
|
|
{
|
|
DNASSERT( ( m_Handle == 0 ) || ( Handle == 0 ) );
|
|
m_Handle = Handle;
|
|
}
|
|
|
|
const CComPortData *ComPortData( void ) const { return &m_ComPortData; }
|
|
const SP_BAUD_RATE GetBaudRate( void ) const { return m_ComPortData.GetBaudRate(); }
|
|
HRESULT SetBaudRate( const SP_BAUD_RATE BaudRate ) { return m_ComPortData.SetBaudRate( BaudRate ); }
|
|
|
|
const SP_STOP_BITS GetStopBits( void ) const { return m_ComPortData.GetStopBits(); }
|
|
HRESULT SetStopBits( const SP_STOP_BITS StopBits ) { return m_ComPortData.SetStopBits( StopBits ); }
|
|
|
|
const SP_PARITY_TYPE GetParity( void ) const { return m_ComPortData.GetParity(); }
|
|
HRESULT SetParity( const SP_PARITY_TYPE Parity ) { return m_ComPortData.SetParity( Parity ); }
|
|
|
|
const SP_FLOW_CONTROL GetFlowControl( void ) const { return m_ComPortData.GetFlowControl(); }
|
|
HRESULT SetFlowControl( const SP_FLOW_CONTROL FlowControl ) { return m_ComPortData.SetFlowControl( FlowControl ); }
|
|
|
|
const CComPortData *GetComPortData( void ) const { return &m_ComPortData; }
|
|
|
|
const GUID *GetEncryptionGuid( void ) const
|
|
{
|
|
if (m_fModem)
|
|
{
|
|
return &g_ModemSPEncryptionGuid;
|
|
}
|
|
else
|
|
{
|
|
return &g_SerialSPEncryptionGuid;
|
|
}
|
|
}
|
|
|
|
const TCHAR *GetPhoneNumber( void ) const { return m_PhoneNumber; }
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CModemEndpoint::SetPhoneNumber"
|
|
HRESULT SetPhoneNumber( const TCHAR *const pPhoneNumber )
|
|
{
|
|
DNASSERT( pPhoneNumber != NULL );
|
|
DNASSERT( lstrlen( pPhoneNumber ) < ( sizeof( m_PhoneNumber ) / sizeof( TCHAR ) ) );
|
|
lstrcpyn( m_PhoneNumber, pPhoneNumber, MAX_PHONE_NUMBER_SIZE );
|
|
return DPN_OK;
|
|
}
|
|
|
|
void *DeviceBindContext( void ) { return &m_dwDeviceID; }
|
|
|
|
CDataPort *GetDataPort( void ) const { return m_pDataPort; }
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CModemEndpoint::SetDataPort"
|
|
void SetDataPort( CDataPort *const pDataPort )
|
|
{
|
|
DNASSERT( ( m_pDataPort == NULL ) || ( pDataPort == NULL ) );
|
|
m_pDataPort = pDataPort;
|
|
}
|
|
|
|
ENDPOINT_TYPE GetType( void ) const { return m_EndpointType; }
|
|
|
|
void *GetUserEndpointContext( void ) const { return m_pUserEndpointContext; }
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CModemEndpoint::SetUserEndpointContext"
|
|
void SetUserEndpointContext( void *const pContext )
|
|
{
|
|
DNASSERT( ( m_pUserEndpointContext == NULL ) || ( pContext == NULL ) );
|
|
m_pUserEndpointContext = pContext;
|
|
}
|
|
|
|
ENDPOINT_STATE GetState( void ) const { return m_State; }
|
|
void SetState( const ENDPOINT_STATE EndpointState );
|
|
CModemSPData *GetSPData( void ) const { return m_pSPData; }
|
|
|
|
CModemCommandData *GetCommandData( void ) const { return m_pCommandHandle; }
|
|
DPNHANDLE GetDisconnectIndicationHandle( void ) const { return this->m_hDisconnectIndicationHandle; }
|
|
void SetDisconnectIndicationHandle( const DPNHANDLE hDisconnectIndicationHandle )
|
|
{
|
|
DNASSERT( ( GetDisconnectIndicationHandle() == 0 ) ||
|
|
( hDisconnectIndicationHandle == 0 ) );
|
|
m_hDisconnectIndicationHandle = hDisconnectIndicationHandle;
|
|
}
|
|
|
|
void CopyConnectData( const SPCONNECTDATA *const pConnectData );
|
|
static void ConnectJobCallback( THREAD_POOL_JOB *const pJobHeader );
|
|
static void CancelConnectJobCallback( THREAD_POOL_JOB *const pJobHeader );
|
|
HRESULT CompleteConnect( void );
|
|
|
|
void CopyListenData( const SPLISTENDATA *const pListenData );
|
|
static void ListenJobCallback( THREAD_POOL_JOB *const pJobHeader );
|
|
static void CancelListenJobCallback( THREAD_POOL_JOB *const pJobHeader );
|
|
HRESULT CompleteListen( void );
|
|
|
|
void CopyEnumQueryData( const SPENUMQUERYDATA *const pEnumQueryData );
|
|
static void EnumQueryJobCallback( THREAD_POOL_JOB *const pJobHeader );
|
|
static void CancelEnumQueryJobCallback( THREAD_POOL_JOB *const pJobHeader );
|
|
HRESULT CompleteEnumQuery( void );
|
|
void OutgoingConnectionEstablished( const HRESULT hCommandResult );
|
|
|
|
HRESULT Open( IDirectPlay8Address *const pHostAddress,
|
|
IDirectPlay8Address *const pAdapterAddress,
|
|
const LINK_DIRECTION LinkDirection,
|
|
const ENDPOINT_TYPE EndpointType );
|
|
HRESULT OpenOnListen( const CModemEndpoint *const pEndpoint );
|
|
void Close( const HRESULT hActiveCommandResult );
|
|
DWORD GetLinkSpeed( void ) const;
|
|
|
|
HRESULT Disconnect( const DPNHANDLE hOldEndpointHandle );
|
|
void SignalDisconnect( const DPNHANDLE hOldEndpointHandle );
|
|
|
|
//
|
|
// send functions
|
|
//
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CModemEndpoint::SendUserData"
|
|
void SendUserData( CModemWriteIOData *const pWriteBuffer )
|
|
{
|
|
DNASSERT( pWriteBuffer != NULL );
|
|
DNASSERT( m_pDataPort != NULL );
|
|
m_pDataPort->SendUserData( pWriteBuffer );
|
|
}
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CModemEndpoint::SendEnumResponseData"
|
|
void SendEnumResponseData( CModemWriteIOData *const pWriteBuffer, const UINT_PTR uRTTIndex )
|
|
{
|
|
DNASSERT( pWriteBuffer != NULL );
|
|
DNASSERT( m_pDataPort != NULL );
|
|
m_pDataPort->SendEnumResponseData( pWriteBuffer, uRTTIndex );
|
|
}
|
|
|
|
void StopEnumCommand( const HRESULT hCommandResult );
|
|
|
|
LINK_DIRECTION GetLinkDirection( void ) const;
|
|
|
|
//
|
|
// dialog settings
|
|
//
|
|
IDirectPlay8Address *GetRemoteHostDP8Address( void ) const;
|
|
IDirectPlay8Address *GetLocalAdapterDP8Address( const ADDRESS_TYPE AddressType ) const;
|
|
|
|
//
|
|
// data processing functions
|
|
//
|
|
void ProcessEnumData( SPRECEIVEDBUFFER *const pReceivedBuffer, const UINT_PTR uRTTIndex );
|
|
void ProcessEnumResponseData( SPRECEIVEDBUFFER *const pReceivedBuffer, const UINT_PTR uRTTIndex );
|
|
void ProcessUserData( CModemReadIOData *const pReadData );
|
|
void ProcessUserDataOnListen( CModemReadIOData *const pReadData );
|
|
|
|
#ifndef DPNBUILD_NOSPUI
|
|
//
|
|
// UI functions
|
|
//
|
|
HRESULT ShowOutgoingSettingsDialog( CModemThreadPool *const pThreadPool );
|
|
HRESULT ShowIncomingSettingsDialog( CModemThreadPool *const pThreadPool );
|
|
void StopSettingsDialog( const HWND hDialog );
|
|
|
|
void SettingsDialogComplete( const HRESULT hDialogReturnCode );
|
|
|
|
HWND ActiveDialogHandle( void ) const { return m_hActiveDialogHandle; }
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CModemEndpoint::SetActiveDialogHandle"
|
|
void SetActiveDialogHandle( const HWND hDialog )
|
|
{
|
|
DNASSERT( ( ActiveDialogHandle() == NULL ) || ( hDialog == NULL ) );
|
|
m_hActiveDialogHandle = hDialog;
|
|
}
|
|
#endif // !DPNBUILD_NOSPUI
|
|
|
|
//
|
|
// port settings
|
|
//
|
|
DWORD GetDeviceID( void ) const
|
|
{
|
|
if (m_fModem)
|
|
{
|
|
return m_dwDeviceID;
|
|
}
|
|
else
|
|
{
|
|
return m_ComPortData.GetDeviceID();
|
|
}
|
|
}
|
|
HRESULT SetDeviceID( const DWORD dwDeviceID )
|
|
{
|
|
if (m_fModem)
|
|
{
|
|
DNASSERT( ( m_dwDeviceID == INVALID_DEVICE_ID ) || ( dwDeviceID == INVALID_DEVICE_ID ) );
|
|
m_dwDeviceID = dwDeviceID;
|
|
return DPN_OK;
|
|
}
|
|
else
|
|
{
|
|
return m_ComPortData.SetDeviceID( dwDeviceID );
|
|
}
|
|
}
|
|
|
|
//
|
|
// pool functions
|
|
//
|
|
static BOOL PoolAllocFunction( void* pvItem, void* pvContext );
|
|
static void PoolInitFunction( void* pvItem, void* pvContext );
|
|
static void PoolReleaseFunction( void* pvItem );
|
|
static void PoolDeallocFunction( void* pvItem );
|
|
|
|
|
|
protected:
|
|
BYTE m_Sig[4]; // debugging signature ('THPL')
|
|
|
|
CModemSPData *m_pSPData; // pointer to SP data
|
|
|
|
BOOL m_fModem;
|
|
|
|
CComPortData m_ComPortData;
|
|
|
|
DWORD m_dwDeviceID;
|
|
TCHAR m_PhoneNumber[ MAX_PHONE_NUMBER_SIZE ];
|
|
|
|
struct
|
|
{
|
|
BOOL fInitialized : 1;
|
|
BOOL fConnectIndicated : 1;
|
|
BOOL fCommandPending : 1;
|
|
BOOL fListenStatusNeedsToBeIndicated : 1;
|
|
} m_Flags;
|
|
|
|
DWORD m_dwEnumSendIndex; // enum send index
|
|
DWORD m_dwEnumSendTimes[ 4 ]; // enum send times
|
|
|
|
union // Local copy of the pending command paramters.
|
|
{ // This data contains the pointers to the active
|
|
SPCONNECTDATA ConnectData; // command, and the user context.
|
|
SPLISTENDATA ListenData; //
|
|
SPENUMQUERYDATA EnumQueryData; //
|
|
} m_CurrentCommandParameters; //
|
|
|
|
CModemCommandData *m_pCommandHandle; // pointer to active command (this is kept to
|
|
// avoid a switch to go through the m_ActveCommandData
|
|
// to find the command handle)
|
|
|
|
HWND m_hActiveDialogHandle; // handle of active dialog
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CModemEndpoint::SetType"
|
|
void SetType( const ENDPOINT_TYPE EndpointType )
|
|
{
|
|
DNASSERT( ( m_EndpointType == ENDPOINT_TYPE_UNKNOWN ) || ( EndpointType == ENDPOINT_TYPE_UNKNOWN ) );
|
|
m_EndpointType = EndpointType;
|
|
}
|
|
|
|
CModemCommandData *CommandHandle( void ) const;
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CModemEndpoint::SetCommandHandle"
|
|
void SetCommandHandle( CModemCommandData *const pCommandHandle )
|
|
{
|
|
DNASSERT( ( m_pCommandHandle == NULL ) || ( pCommandHandle == NULL ) );
|
|
m_pCommandHandle = pCommandHandle;
|
|
}
|
|
|
|
HRESULT CommandResult( void ) const { return m_hPendingCommandResult; }
|
|
void SetCommandResult( const HRESULT hCommandResult ) { m_hPendingCommandResult = hCommandResult; }
|
|
|
|
void CompletePendingCommand( const HRESULT hResult );
|
|
HRESULT PendingCommandResult( void ) const { return m_hPendingCommandResult; }
|
|
|
|
static void EnumCompleteWrapper( const HRESULT hCompletionCode, void *const pContext );
|
|
static void EnumTimerCallback( void *const pContext );
|
|
void EnumComplete( const HRESULT hCompletionCode );
|
|
|
|
HRESULT SignalConnect( SPIE_CONNECT *const pConnectData );
|
|
const void *GetDeviceContext( void ) const;
|
|
void CleanUpCommand( void );
|
|
|
|
#ifndef DPNBUILD_ONLYONETHREAD
|
|
DNCRITICAL_SECTION m_Lock; // critical section
|
|
#endif // !DPNBUILD_ONLYONETHREAD
|
|
DPNHANDLE m_Handle; // active handle for this endpoint
|
|
volatile ENDPOINT_STATE m_State; // endpoint state
|
|
|
|
volatile LONG m_lCommandRefCount; // Command ref count. When this
|
|
// goes to zero, the endpoint unbinds
|
|
// from the network
|
|
volatile LONG m_iRefCount;
|
|
|
|
ENDPOINT_TYPE m_EndpointType; // type of endpoint
|
|
CDataPort *m_pDataPort; // pointer to associated data port
|
|
|
|
HRESULT m_hPendingCommandResult; // command result returned when endpoint RefCount == 0
|
|
DPNHANDLE m_hDisconnectIndicationHandle; // handle to be indicated with disconnect notification.
|
|
|
|
void *m_pUserEndpointContext; // user context associated with this endpoint
|
|
|
|
//
|
|
// make copy constructor and assignment operator private and unimplemented
|
|
// to prevent illegal copies from being made
|
|
//
|
|
CModemEndpoint( const CModemEndpoint & );
|
|
CModemEndpoint& operator=( const CModemEndpoint & );
|
|
};
|
|
|
|
#undef DPF_MODNAME
|
|
|
|
#endif // __ENDPOINT_H__
|
|
|