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.
 
 
 
 
 
 

811 lines
20 KiB

/*==========================================================================
*
* Copyright (C) 1999-2000 Microsoft Corporation. All Rights Reserved.
*
* File: SPData.cpp
* Content: Global variables for the DNSerial service provider in class
* format.
*
*
* History:
* Date By Reason
* ==== == ======
* 03/15/99 jtk Dereived from Locals.cpp
***************************************************************************/
#include "dnmdmi.h"
//**********************************************************************
// Constant definitions
//**********************************************************************
// default number of command descriptors to create
#define DEFAULT_COMMAND_POOL_SIZE 20
#define COMMAND_POOL_GROW_SIZE 5
//**********************************************************************
// Macro definitions
//**********************************************************************
//**********************************************************************
// Structure definitions
//**********************************************************************
//**********************************************************************
// Variable definitions
//**********************************************************************
//**********************************************************************
// Function prototypes
//**********************************************************************
//**********************************************************************
// Function definitions
//**********************************************************************
//**********************************************************************
// ------------------------------
// CModemSPData::CModemSPData - constructor
//
// Entry: Nothing
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CModemSPData::CModemSPData"
CModemSPData::CModemSPData():
m_lRefCount( 0 ),
m_lObjectRefCount( 0 ),
m_hShutdownEvent( NULL ),
m_SPType( TYPE_UNKNOWN ),
m_State( SPSTATE_UNINITIALIZED ),
m_pThreadPool( NULL ),
m_fLockInitialized( FALSE ),
m_fHandleTableInitialized( FALSE ),
m_fDataPortDataLockInitialized( FALSE ),
m_fInterfaceGlobalsInitialized( FALSE )
{
m_Sig[0] = 'S';
m_Sig[1] = 'P';
m_Sig[2] = 'D';
m_Sig[3] = 'T';
memset( &m_InitData, 0x00, sizeof( m_InitData ) );
memset( &m_DataPortList, 0x00, sizeof( m_DataPortList ) );
memset( &m_COMInterface, 0x00, sizeof( m_COMInterface ) );
#ifndef DPNBUILD_LIBINTERFACE
DNInterlockedIncrement( &g_lModemOutstandingInterfaceCount );
#endif // ! DPNBUILD_LIBINTERFACE
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CModemSPData::~CModemSPData - destructor
//
// Entry: Nothing
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CModemSPData::~CModemSPData"
CModemSPData::~CModemSPData()
{
UINT_PTR uIndex;
DNASSERT( m_lRefCount == 0 );
DNASSERT( m_lObjectRefCount == 0 );
DNASSERT( m_hShutdownEvent == NULL );
DNASSERT( m_SPType == TYPE_UNKNOWN );
DNASSERT( m_State == SPSTATE_UNINITIALIZED );
DNASSERT( m_pThreadPool == NULL );
uIndex = LENGTHOF( m_DataPortList );
while ( uIndex > 0 )
{
uIndex--;
DNASSERT( m_DataPortList[ uIndex ] == NULL );
}
DNASSERT( m_fLockInitialized == FALSE );
DNASSERT( m_fHandleTableInitialized == FALSE );
DNASSERT( m_fDataPortDataLockInitialized == FALSE );
DNASSERT( m_fInterfaceGlobalsInitialized == FALSE );
#ifndef DPNBUILD_LIBINTERFACE
DNInterlockedDecrement( &g_lModemOutstandingInterfaceCount );
#endif // ! DPNBUILD_LIBINTERFACE
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CModemSPData::Initialize - intialize
//
// Entry: Pointer to DirectNet
//
// Exit: Error code
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CModemSPData::Initialize"
HRESULT CModemSPData::Initialize( const SP_TYPE SPType,
IDP8ServiceProviderVtbl *const pVtbl )
{
HRESULT hr;
DNASSERT( pVtbl != NULL );
//
// initialize
//
hr = DPN_OK;
DNASSERT( m_lRefCount == 1 );
DNASSERT( m_lObjectRefCount == 0 );
DNASSERT( GetType() == TYPE_UNKNOWN );
DNASSERT( GetType() == TYPE_UNKNOWN );
m_SPType = SPType;
DNASSERT( m_COMInterface.m_pCOMVtbl == NULL );
m_COMInterface.m_pCOMVtbl = pVtbl;
DNASSERT( m_fLockInitialized == FALSE );
DNASSERT( m_fDataPortDataLockInitialized == FALSE );
DNASSERT( m_fInterfaceGlobalsInitialized == FALSE );
//
// attempt to initialize shutdown event
//
DNASSERT( m_hShutdownEvent == NULL );
m_hShutdownEvent = DNCreateEvent( NULL, // pointer to security (none)
TRUE, // manual reset
TRUE, // start signalled (so close can be called without any endpoints being created)
NULL // pointer to name (none)
);
if ( m_hShutdownEvent == NULL )
{
DWORD dwError;
dwError = GetLastError();
DPFX(DPFPREP, 0, "Failed to create event for shutting down spdata!" );
DisplayErrorCode( 0, dwError );
}
//
// initialize critical sections
//
if ( DNInitializeCriticalSection( &m_Lock ) == FALSE )
{
hr = DPNERR_OUTOFMEMORY;
DPFX(DPFPREP, 0, "Failed to initialize SP lock!" );
goto Failure;
}
DebugSetCriticalSectionRecursionCount( &m_Lock, 0 );
DebugSetCriticalSectionGroup( &m_Lock, &g_blDPNModemCritSecsHeld ); // separate dpnmodem CSes from the rest of DPlay's CSes
m_fLockInitialized = TRUE;
hr = m_HandleTable.Initialize();
if ( hr != DPN_OK )
{
DPFX(DPFPREP, 0, "Failed to initialize handle table!" );
DisplayDNError( 0, hr );
goto Failure;
}
m_fHandleTableInitialized = TRUE;
if ( DNInitializeCriticalSection( &m_DataPortDataLock ) == FALSE )
{
hr = DPNERR_OUTOFMEMORY;
DPFX(DPFPREP, 0, "Failed to initialize data port data lock!" );
goto Failure;
}
DebugSetCriticalSectionRecursionCount( &m_DataPortDataLock, 0 );
DebugSetCriticalSectionGroup( &m_DataPortDataLock, &g_blDPNModemCritSecsHeld ); // separate dpnmodem CSes from the rest of DPlay's CSes
m_fDataPortDataLockInitialized = TRUE;
//
// get a thread pool
//
DNASSERT( m_pThreadPool == NULL );
hr = InitializeInterfaceGlobals( this );
if ( hr != DPN_OK )
{
DPFX(DPFPREP, 0, "Failed to create thread pool!" );
DisplayDNError( 0, hr );
goto Failure;
}
m_fInterfaceGlobalsInitialized = TRUE;
Exit:
if ( hr != DPN_OK )
{
DPFX(DPFPREP, 0, "Problem with CModemSPData::Initialize" );
DisplayDNError( 0, hr );
}
return hr;
Failure:
Deinitialize();
goto Exit;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CModemSPData::Shutdown - shut down this set of SP data
//
// Entry: Nothing
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CModemSPData::Shutdown"
void CModemSPData::Shutdown( void )
{
BOOL fLooping;
//
// Unbind this interface from the globals. This will cause a closure of all
// of the I/O which will release endpoints, socket ports and then this data.
//
if ( m_fInterfaceGlobalsInitialized != FALSE )
{
DeinitializeInterfaceGlobals( this );
DNASSERT( GetThreadPool() != NULL );
m_fInterfaceGlobalsInitialized = FALSE;
}
SetState( SPSTATE_CLOSING );
DNASSERT( m_hShutdownEvent != NULL );
fLooping = TRUE;
while ( fLooping != FALSE )
{
switch ( DNWaitForSingleObjectEx( m_hShutdownEvent, INFINITE, TRUE ) )
{
case WAIT_OBJECT_0:
{
fLooping = FALSE;
break;
}
case WAIT_IO_COMPLETION:
{
break;
}
default:
{
DNASSERT( FALSE );
break;
}
}
}
if ( DNCloseHandle( m_hShutdownEvent ) == FALSE )
{
DWORD dwError;
dwError = GetLastError();
DPFX(DPFPREP, 0, "Failed to close shutdown event!" );
DisplayErrorCode( 0, dwError );
}
m_hShutdownEvent = NULL;
if ( DP8SPCallbackInterface() != NULL)
{
IDP8SPCallback_Release( DP8SPCallbackInterface() );
memset( &m_InitData, 0x00, sizeof( m_InitData ) );
}
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CModemSPData::Deinitialize - deinitialize
//
// Entry: Nothing
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CModemSPData::Deinitialize"
void CModemSPData::Deinitialize( void )
{
DPFX(DPFPREP, 9, "Entering CModemSPData::Deinitialize" );
//
// deinitialize interface globals
//
if ( m_fInterfaceGlobalsInitialized != FALSE )
{
DeinitializeInterfaceGlobals( this );
DNASSERT( GetThreadPool() != NULL );
m_fInterfaceGlobalsInitialized = FALSE;
}
if ( m_fDataPortDataLockInitialized != FALSE )
{
DNDeleteCriticalSection( &m_DataPortDataLock );
m_fDataPortDataLockInitialized = FALSE;
}
if ( m_fHandleTableInitialized != FALSE )
{
m_HandleTable.Deinitialize();
m_fHandleTableInitialized = FALSE;
}
if ( m_fLockInitialized != FALSE )
{
DNDeleteCriticalSection( &m_Lock );
m_fLockInitialized = FALSE;
}
m_COMInterface.m_pCOMVtbl = NULL;
SetState( SPSTATE_UNINITIALIZED );
m_SPType = TYPE_UNKNOWN;
if ( GetThreadPool() != NULL )
{
GetThreadPool()->DecRef();
SetThreadPool( NULL );
}
if ( m_hShutdownEvent != NULL )
{
if ( DNCloseHandle( m_hShutdownEvent ) == FALSE )
{
DWORD dwError;
dwError = GetLastError();
DPFX(DPFPREP, 0, "Failed to close shutdown handle!" );
DisplayErrorCode( 0, dwError );
}
m_hShutdownEvent = NULL;
}
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CModemSPData::SetCallbackData - set data for SP callbacks to application
//
// Entry: Pointer to initialization data
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CModemSPData::SetCallbackData"
void CModemSPData::SetCallbackData( const SPINITIALIZEDATA *const pInitData )
{
DNASSERT( pInitData != NULL );
DNASSERT( pInitData->dwFlags == SP_SESSION_TYPE_PEER ||
pInitData->dwFlags == SP_SESSION_TYPE_CLIENT ||
pInitData->dwFlags == SP_SESSION_TYPE_SERVER ||
pInitData->dwFlags == 0);
m_InitData.dwFlags = pInitData->dwFlags;
DNASSERT( pInitData->pIDP != NULL );
m_InitData.pIDP = pInitData->pIDP;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CModemSPData::BindEndpoint - bind endpoint to a data port
//
// Entry: Pointer to endpoint
// DeviceID
// Device context
//
// Exit: Error code
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CModemSPData::BindEndpoint"
HRESULT CModemSPData::BindEndpoint( CModemEndpoint *const pEndpoint,
const DWORD dwDeviceID,
const void *const pDeviceContext )
{
HRESULT hr;
CDataPort *pDataPort;
BOOL fDataPortDataLocked;
BOOL fDataPortCreated;
BOOL fDataPortBoundToNetwork;
DPFX(DPFPREP, 9, "(0x%p) Parameters: (0x%p, %u, 0x%p)",
this, pEndpoint, dwDeviceID, pDeviceContext);
//
// intialize
//
hr = DPN_OK;
pDataPort = NULL;
fDataPortDataLocked = FALSE;
fDataPortCreated = FALSE;
fDataPortBoundToNetwork = FALSE;
LockDataPortData();
fDataPortDataLocked = TRUE;
if ( m_DataPortList[ dwDeviceID ] != NULL )
{
pDataPort = m_DataPortList[ dwDeviceID ];
}
else
{
DATA_PORT_POOL_CONTEXT DataPortPoolContext;
memset( &DataPortPoolContext, 0x00, sizeof( DataPortPoolContext ) );
DataPortPoolContext.pSPData = this;
pDataPort = CreateDataPort( &DataPortPoolContext );
if ( pDataPort == NULL )
{
hr = DPNERR_OUTOFMEMORY;
DPFX(DPFPREP, 0, "Failed to create new data port!" );
goto Failure;
}
fDataPortCreated = TRUE;
hr = GetThreadPool()->CreateDataPortHandle( pDataPort );
if ( hr != DPN_OK )
{
DPFX(DPFPREP, 0, "Failed to create handle for data port!" );
DisplayDNError( 0, hr );
goto Failure;
}
hr = pDataPort->BindToNetwork( dwDeviceID, pDeviceContext );
if ( hr != DPN_OK )
{
DPFX(DPFPREP, 0, "Failed to bind data port to network!" );
DisplayDNError( 0, hr );
goto Failure;
}
fDataPortBoundToNetwork = TRUE;
//
// update the list, keep the reference added by 'CreateDataPort' as it
// will be cleaned when the data port is removed from the active list.
//
m_DataPortList[ dwDeviceID ] = pDataPort;
}
DNASSERT( pDataPort != NULL );
pDataPort->EndpointAddRef();
hr = pDataPort->BindEndpoint( pEndpoint, pEndpoint->GetType() );
if ( hr != DPN_OK )
{
pDataPort->EndpointDecRef();
DPFX(DPFPREP, 0, "Failed to bind endpoint!" );
DisplayDNError( 0, hr );
goto Failure;
}
Exit:
if ( fDataPortDataLocked != FALSE )
{
UnlockDataPortData();
fDataPortDataLocked = FALSE;
}
DPFX(DPFPREP, 9, "(0x%p) Returning [0x%lx]", this, hr);
return hr;
Failure:
if ( pDataPort != NULL )
{
if ( fDataPortBoundToNetwork != FALSE )
{
pDataPort->UnbindFromNetwork();
fDataPortBoundToNetwork = FALSE;
}
if ( fDataPortCreated != FALSE )
{
if ( pDataPort->GetHandle() != 0 )
{
GetThreadPool()->CloseDataPortHandle( pDataPort );
DNASSERT( pDataPort->GetHandle() == 0 );
}
pDataPort->DecRef();
fDataPortCreated = FALSE;
}
pDataPort = NULL;
}
goto Exit;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CModemSPData::UnbindEndpoint - unbind an endpoint from a dataport
//
// Entry: Pointer to endpoint
// Endpoint type
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CModemSPData::UnbindEndpoint"
void CModemSPData::UnbindEndpoint( CModemEndpoint *const pEndpoint, const ENDPOINT_TYPE EndpointType )
{
CDataPort *pDataPort;
DWORD dwDeviceID;
BOOL fCleanUpDataPort;
DPFX(DPFPREP, 9, "(0x%p) Parameters: (0x%p, %u)", this, pEndpoint, EndpointType);
DNASSERT( pEndpoint != NULL );
//
// initialize
//
pDataPort = NULL;
fCleanUpDataPort = FALSE;
pDataPort = pEndpoint->GetDataPort();
dwDeviceID = pDataPort->GetDeviceID();
LockDataPortData();
pDataPort->UnbindEndpoint( pEndpoint, EndpointType );
if ( pDataPort->EndpointDecRef() == 0 )
{
DNASSERT( m_DataPortList[ dwDeviceID ] == pDataPort );
m_DataPortList[ dwDeviceID ] = NULL;
fCleanUpDataPort = TRUE;
}
UnlockDataPortData();
if ( fCleanUpDataPort != FALSE )
{
pDataPort->DecRef();
fCleanUpDataPort = FALSE;
}
DPFX(DPFPREP, 9, "(0x%p) Leave", this);
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CModemSPData::GetNewEndpoint - get a new endpoint
//
// Entry: Nothing
//
// Exit: Pointer to new endpoint
// NULL = out of memory
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CModemSPData::GetNewEndpoint"
CModemEndpoint *CModemSPData::GetNewEndpoint( void )
{
HRESULT hTempResult;
CModemEndpoint *pEndpoint;
DPNHANDLE hEndpoint;
ENDPOINT_POOL_CONTEXT PoolContext;
DPFX(DPFPREP, 9, "(0x%p) Enter", this);
//
// initialize
//
pEndpoint = NULL;
hEndpoint = 0;
memset( &PoolContext, 0x00, sizeof( PoolContext ) );
PoolContext.pSPData = this;
pEndpoint = CreateEndpoint( &PoolContext );
if ( pEndpoint == NULL )
{
DPFX(DPFPREP, 0, "Failed to create endpoint!" );
goto Failure;
}
hTempResult = m_HandleTable.Create( pEndpoint, &hEndpoint );
if ( hTempResult != DPN_OK )
{
DNASSERT( hEndpoint == 0 );
DPFX(DPFPREP, 0, "Failed to create endpoint handle!" );
DisplayErrorCode( 0, hTempResult );
goto Failure;
}
pEndpoint->SetHandle( hEndpoint );
pEndpoint->AddCommandRef();
pEndpoint->DecRef();
Exit:
DPFX(DPFPREP, 9, "(0x%p) Returning [0x%p]", this, pEndpoint);
return pEndpoint;
Failure:
if ( hEndpoint != 0 )
{
m_HandleTable.Destroy( hEndpoint, NULL );
hEndpoint = 0;
}
if ( pEndpoint != NULL )
{
pEndpoint->DecRef();
pEndpoint = NULL;
}
goto Exit;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CModemSPData::EndpointFromHandle - get endpoint from handle
//
// Entry: Handle
//
// Exit: Pointer to endpoint
// NULL = invalid handle
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CModemSPData::EndpointFromHandle"
CModemEndpoint *CModemSPData::EndpointFromHandle( const DPNHANDLE hEndpoint )
{
CModemEndpoint *pEndpoint;
DPFX(DPFPREP, 9, "(0x%p) Parameters: (0x%p)", this, hEndpoint);
pEndpoint = NULL;
m_HandleTable.Lock();
if (SUCCEEDED(m_HandleTable.Find( hEndpoint, (PVOID*)&pEndpoint )))
{
pEndpoint->AddCommandRef();
}
m_HandleTable.Unlock();
DPFX(DPFPREP, 9, "(0x%p) Returning [0x%p]", this, pEndpoint);
return pEndpoint;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CModemSPData::CloseEndpointHandle - close endpoint handle
//
// Entry: Poiner to endpoint
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CModemSPData::CloseEndpointHandle"
void CModemSPData::CloseEndpointHandle( CModemEndpoint *const pEndpoint )
{
DPNHANDLE Handle;
DNASSERT( pEndpoint != NULL );
Handle = pEndpoint->GetHandle();
DPFX(DPFPREP, 9, "(0x%p) Parameters: (0x%p {handle = 0x%p})",
this, pEndpoint, Handle);
if (SUCCEEDED(m_HandleTable.Destroy( Handle, NULL )))
{
pEndpoint->DecCommandRef();
}
DPFX(DPFPREP, 9, "(0x%p) Leave", this);
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CModemSPData::GetEndpointAndCloseHandle - get endpoint from handle and close the
// handle
//
// Entry: Handle
//
// Exit: Pointer to endpoint (it needs a call to 'DecCommandRef' when done)
// NULL = invalid handle
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CModemSPData::GetEndpointAndCloseHandle"
CModemEndpoint *CModemSPData::GetEndpointAndCloseHandle( const DPNHANDLE hEndpoint )
{
CModemEndpoint *pEndpoint;
DPFX(DPFPREP, 9, "(0x%p) Parameters: (0x%p)", this, hEndpoint);
//
// initialize
//
pEndpoint = NULL;
if (SUCCEEDED( m_HandleTable.Destroy( hEndpoint, (PVOID*)&pEndpoint )))
{
pEndpoint->AddRef();
}
DPFX(DPFPREP, 9, "(0x%p) Returning [0x%p]", this, pEndpoint);
return pEndpoint;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CModemSPData::DestroyThisObject - destroy this object
//
// Entry: Nothing
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CModemSPData::DestroyThisObject"
void CModemSPData::DestroyThisObject( void )
{
Deinitialize();
delete this; // maybe a little too extreme......
}
//**********************************************************************