2025-04-27 07:49:33 -04:00

564 lines
15 KiB
C++

/*==========================================================================
*
* Copyright (C) 1999-2000 Microsoft Corporation. All Rights Reserved.
*
* File: IOData.cpp
* Content: Functions for IO structures
*
*
* History:
* Date By Reason
* ==== == ======
* 11/25/98 jtk Created
* 02/11/2000 jtk Derived from IODAta.h
***************************************************************************/
#include "dnmdmi.h"
#undef DPF_SUBCOMP
#define DPF_SUBCOMP DN_SUBCOMP_MODEM
//**********************************************************************
// Constant definitions
//**********************************************************************
//**********************************************************************
// Macro definitions
//**********************************************************************
//**********************************************************************
// Structure definitions
//**********************************************************************
//**********************************************************************
// Variable definitions
//**********************************************************************
//**********************************************************************
// Function prototypes
//**********************************************************************
//**********************************************************************
// ------------------------------
// CIOData::CIOData - constructor
//
// Entry: Nothing
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CIOData::CIOData"
CIOData::CIOData():
#ifdef WINNT
m_NTIOOperationType( NT_IO_OPERATION_UNKNOWN ),
#endif
#ifdef WIN95
m_fWin9xOperationPending( FALSE ),
#endif
m_pDataPort( NULL )
{
memset( &m_Overlap, 0x00, sizeof( m_Overlap ) );
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CIOData::~CIOData - destructor
//
// Entry: Nothing
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CIOData::~CIOData"
CIOData::~CIOData()
{
DNASSERT( DataPort() == NULL );
#ifdef WIN95
DNASSERT( OverlapEvent() == NULL );
DNASSERT( Win9xOperationPending() == FALSE );
#endif
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CReadIOData::CReadIOData - constructor
//
// Entry: Nothing
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CReadIOData::CReadIOData"
CReadIOData::CReadIOData():
m_dwWin9xReceiveErrorReturn( ERROR_SUCCESS ),
jkm_dwOverlappedBytesReceived( 0 ),
jkm_dwImmediateBytesReceived( 0 ),
m_ReadState( READ_STATE_UNKNOWN ),
m_dwBytesToRead( 0 ),
m_dwReadOffset( 0 ),
m_lRefCount( 0 ),
m_pThreadPool( NULL )
{
m_Sig[0] = 'R';
m_Sig[1] = 'I';
m_Sig[2] = 'O';
m_Sig[3] = 'D';
m_OutstandingReadListLinkage.Initialize();
memset( &m_ReceiveBuffer, 0x00, sizeof( m_ReceiveBuffer ) );
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CReadIOData::~CReadIOData - destructor
//
// Entry: Nothing
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CReadIOData::~CReadIOData"
CReadIOData::~CReadIOData()
{
DNASSERT( m_OutstandingReadListLinkage.IsEmpty() != FALSE );
DNASSERT( m_ReadState == READ_STATE_UNKNOWN );
DNASSERT( m_dwBytesToRead == 0 );
DNASSERT( m_dwReadOffset == 0 );
DNASSERT( m_lRefCount == 0 );
DNASSERT( m_pThreadPool == NULL );
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CReadIOData::PoolAllocFunction - called when new CReadIOData is allocated
//
// Entry: Context (handle of read complete event)
//
// Exit: Boolean indicating success
// TRUE = success
// FALSE = failure
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CReadIOData::PoolAllocFunction"
BOOL CReadIOData::PoolAllocFunction( HANDLE Context )
{
BOOL fReturn;
//
// initialize
//
fReturn = TRUE;
DNASSERT( m_OutstandingReadListLinkage.IsEmpty() != FALSE );
DNASSERT( m_ReadState == READ_STATE_UNKNOWN );
DNASSERT( m_dwBytesToRead == 0 );
DNASSERT( m_dwReadOffset == 0 );
DNASSERT( jkm_dwOverlappedBytesReceived == 0 );
#ifdef WIN95
DNASSERT( Win9xOperationPending() == FALSE );
#endif
memset( &m_SPReceivedBuffer, 0x00, sizeof( m_SPReceivedBuffer ) );
m_SPReceivedBuffer.BufferDesc.pBufferData = &m_ReceiveBuffer.ReceivedData[ sizeof( m_ReceiveBuffer.MessageHeader ) ];
//
// set the appropriate callback
//
#ifdef WINNT
//
// WinNT, always use IO completion ports
//
DNASSERT( Context == NULL );
DNASSERT( NTIOOperationType() == NT_IO_OPERATION_UNKNOWN );
SetNTIOOperationType( NT_IO_OPERATION_RECEIVE );
#else // WIN95
//
// Win9x
//
DNASSERT( Context != NULL );
DNASSERT( OverlapEvent() == NULL );
#endif
return fReturn;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CReadIOData::PoolInitFunction - called when new item is grabbed from the pool
//
// Entry: Context (read complete event)
//
// Exit: Boolean indicating success
// TRUE = success
// FALSE = failure
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CReadIOData::PoolInitFunction"
BOOL CReadIOData::PoolInitFunction( HANDLE Context )
{
DNASSERT( m_OutstandingReadListLinkage.IsEmpty() != FALSE );
DNASSERT( m_dwBytesToRead == 0 );
// DNASSERT( m_dwBytesReceived == 0 );
DNASSERT( m_dwReadOffset == 0 );
DNASSERT( jkm_dwOverlappedBytesReceived == 0 );
DNASSERT( m_SPReceivedBuffer.BufferDesc.pBufferData == &m_ReceiveBuffer.ReceivedData[ sizeof( m_ReceiveBuffer.MessageHeader ) ] );
DNASSERT( DataPort() == NULL );
#ifdef WIN95
DNASSERT( Win9xOperationPending() == FALSE );
SetOverlapEvent( Context );
#endif
return TRUE;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CReadIOData::PoolReleaseFunction - called when CReadIOData is returned to pool
//
// Entry: Nothing
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CReadIOData::PoolReleaseFunction"
void CReadIOData::PoolReleaseFunction( void )
{
DNASSERT( m_OutstandingReadListLinkage.IsEmpty() != FALSE );
m_ReadState = READ_STATE_UNKNOWN;
m_dwBytesToRead = 0;
m_dwReadOffset = 0;
jkm_dwOverlappedBytesReceived = 0;
#ifdef WIN95
DNASSERT( Win9xOperationPending() == FALSE );
SetOverlapEvent( NULL );
#endif
SetDataPort( NULL );
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CReadIOData::PoolDeallocFunction - called when CReadIOData is deallocated
//
// Entry: Nothing
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CReadIOData::PoolDeallocFunction"
void CReadIOData::PoolDeallocFunction( void )
{
DNASSERT( m_OutstandingReadListLinkage.IsEmpty() != FALSE );
DNASSERT( m_dwBytesToRead == 0 );
DNASSERT( m_dwReadOffset == 0 );
#ifdef WIN95
DNASSERT( Win9xOperationPending() == FALSE );
#endif
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CRedaIOData::ReturnSelfToPool - return this item to the pool
//
// Entry: Nothing
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CReadIOData::ReturnSelfToPool"
void CReadIOData::ReturnSelfToPool( void )
{
CThreadPool *pThreadPool;
DNASSERT( m_lRefCount == 0 );
DNASSERT( m_pThreadPool != NULL );
pThreadPool = m_pThreadPool;
SetThreadPool( NULL );
pThreadPool->ReturnReadIOData( this );
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CWriteIOData::CWriteIOData - constructor
//
// Entry: Nothing
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CWriteIOData::CWriteIOData"
CWriteIOData::CWriteIOData():
m_pNext( NULL ),
m_pBuffers( NULL ),
m_uBufferCount( 0 ),
m_pCommand( NULL ),
m_SendCompleteAction( SEND_COMPLETE_ACTION_UNKNOWN ),
jkm_hSendResult( DPN_OK ),
jkm_dwOverlappedBytesSent( 0 ),
jkm_dwImmediateBytesSent( 0 )
{
m_Sig[0] = 'W';
m_Sig[1] = 'I';
m_Sig[2] = 'O';
m_Sig[3] = 'D';
m_OutstandingWriteListLinkage.Initialize();
memset( &m_DataBuffer, 0x00, sizeof( m_DataBuffer ) );
m_DataBuffer.MessageHeader.SerialSignature = SERIAL_HEADER_START;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CWriteIOData::~CWriteIOData - destructor
//
// Entry: Nothing
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CWriteIOData::~CWriteIOData"
CWriteIOData::~CWriteIOData()
{
DNASSERT( m_pBuffers == NULL );
DNASSERT( m_uBufferCount == 0 );
DNASSERT( m_pCommand == NULL );
DNASSERT( m_SendCompleteAction == SEND_COMPLETE_ACTION_UNKNOWN );
DNASSERT( m_OutstandingWriteListLinkage.IsEmpty() != FALSE );
// //
// // don't bother checking the send hResult or the count of byes sent
// //
DNASSERT( m_DataBuffer.MessageHeader.SerialSignature == SERIAL_HEADER_START );
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CWriteIOData::PoolAllocFunction - called when new CWriteIOData is allocated
//
// Entry: Context (handle of write completion event)
//
// Exit: Boolean indicating success
// TRUE = allocation succeeded
// FALSE = allocation failed
//
// Note: We always want a command structure associated with CWriteIOData
// so we don't need to grab a new command from the command pool each
// time a CWriteIOData entry is removed from its pool. This is done
// for speed.
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CWriteIOData::PoolAllocFunction"
BOOL CWriteIOData::PoolAllocFunction( HANDLE Context )
{
BOOL fReturn;
CCommandData *pCommand;
#ifdef WIN95
DNASSERT( Context != NULL );
#endif
DNASSERT( m_pNext == NULL );
DNASSERT( m_pBuffers == NULL );
DNASSERT( m_uBufferCount == 0 );
DNASSERT( jkm_dwOverlappedBytesSent == 0 );
DNASSERT( m_pCommand == NULL );
DNASSERT( m_SendCompleteAction == SEND_COMPLETE_ACTION_UNKNOWN );
DNASSERT( m_OutstandingWriteListLinkage.IsEmpty() != FALSE );
//
// initialize
//
fReturn = TRUE;
pCommand = CreateCommand();
if ( pCommand == NULL )
{
DPFX(DPFPREP, 0, "Could not get command when allocating new CWriteIOData!" );
fReturn = FALSE;
goto Exit;
}
//
// associate this command with the WriteData, clear the command descriptor
// because the command isn't really being used yet, and it'll
// cause an ASSERT when it's removed from the WriteIOData pool.
//
m_pCommand = pCommand;
//
// set the appropriate IO function
//
#ifdef WINNT
//
// WinNT, we'll always use completion ports
//
DNASSERT( NTIOOperationType() == NT_IO_OPERATION_UNKNOWN );
SetNTIOOperationType( NT_IO_OPERATION_SEND );
#else // WIN95
//
// Win9x
//
DNASSERT( OverlapEvent() == NULL );
#endif
Exit:
return fReturn;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CWriteIOData::PoolInitFunction - called when new CWriteIOData is removed from pool
//
// Entry: Nothing
//
// Exit: Boolean indicating success
// TRUE = success
// FALSE = failure
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CWriteIOData::PoolInitFunction"
BOOL CWriteIOData::PoolInitFunction( HANDLE Context )
{
BOOL fReturn;
//
// initialize
//
fReturn = TRUE;
DNASSERT( m_pNext == NULL );
DNASSERT( m_pBuffers == NULL );
DNASSERT( m_uBufferCount == 0 );
DNASSERT( jkm_dwOverlappedBytesSent == 0 );
DNASSERT( m_pCommand != NULL );
m_pCommand->SetDescriptor();
DNASSERT( m_pCommand->GetDescriptor() != NULL_DESCRIPTOR );
DNASSERT( m_pCommand->GetUserContext() == NULL );
DNASSERT( m_SendCompleteAction == SEND_COMPLETE_ACTION_UNKNOWN );
DNASSERT( m_OutstandingWriteListLinkage.IsEmpty() != FALSE );
DNASSERT( DataPort() == NULL );
#ifdef WIN95
DNASSERT( Win9xOperationPending() == FALSE );
SetOverlapEvent( Context );
#endif
return fReturn;
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CWriteIOData::PoolReleaseFunction - called when CWriteIOData is returned to pool
//
// Entry: Nothing
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CWriteIOData::PoolReleaseFunction"
void CWriteIOData::PoolReleaseFunction( void )
{
DNASSERT( m_pCommand != NULL );
m_pCommand->Reset();
DNASSERT( m_OutstandingWriteListLinkage.IsEmpty() != FALSE );
#ifdef WIN95
DNASSERT( Win9xOperationPending() == FALSE );
SetOverlapEvent( NULL );
#endif
m_pBuffers = NULL;
m_uBufferCount = 0;
jkm_dwOverlappedBytesSent = 0;
m_pNext = NULL;
m_SendCompleteAction = SEND_COMPLETE_ACTION_UNKNOWN;
SetDataPort( NULL );
DEBUG_ONLY( memset( &m_DataBuffer.Data[ 1 ], 0x00, sizeof( m_DataBuffer.Data ) - 1 ) );
}
//**********************************************************************
//**********************************************************************
// ------------------------------
// CWriteIOData::PoolDeallocFunction - called when new CWriteIOData is deallocated
//
// Entry: Nothing
//
// Exit: Nothing
// ------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CWriteIOData::PoolDeallocFunction"
void CWriteIOData::PoolDeallocFunction( void )
{
DNASSERT( m_pCommand != NULL );
m_pCommand->DecRef();
m_pCommand = NULL;
DNASSERT( m_OutstandingWriteListLinkage.IsEmpty() != FALSE );
DNASSERT( m_pBuffers == NULL );
DNASSERT( m_uBufferCount == 0 );
DNASSERT( m_pCommand == NULL );
#ifdef WIN95
DNASSERT( OverlapEvent() == NULL );
#endif
}
//**********************************************************************