📄 tcpserver.c
字号:
);
}
VOID
TCPS_ReceiveCompletion(
PVOID UserCompletionContext,
PIO_STATUS_BLOCK IoStatusBlock,
ULONG Reserved
)
{
PTCPS_SESSION pSession = (PTCPS_SESSION )UserCompletionContext;
PTCPS_SERVER pServer = (PTCPS_SERVER )pSession->m_pServer;
NTSTATUS Status = IoStatusBlock->Status;
ULONG nByteCount = IoStatusBlock->Information;
if( NT_SUCCESS( Status ) )
{
KdPrint(( "TCPS_ReceiveCompletion: Received %d Bytes\n", nByteCount ));
}
else
{
KdPrint(( "TCPS_ReceiveCompletion: Status 0x%8.8X\n", Status ));
}
//
// Check On State
//
//
// Handle Disconnect Or Transfer Failure
//
// if( !NT_SUCCESS( Status ) || !nByteCount )
if( !nByteCount )
{
//
// Build Disconnect Call
//
Status = KS_Disconnect(
&pSession->m_KS_Endpoint,
NULL, // UserCompletionEvent
TCPS_DisconnectCallback, // UserCompletionRoutine
pSession, // UserCompletionContext
NULL, // pIoStatusBlock
0 // Disconnect Flags
);
return;
}
//
// Update Statistics
//
pSession->m_nBytesReceived += nByteCount;
//
// Start Another Receive On Same Buffer
//
(pSession->m_pReceiveMdl)->Next = NULL; // IMPORTANT!!!
Status = KS_ReceiveOnEndpoint(
&pSession->m_KS_Endpoint,
NULL, // User Completion Event
TCPS_ReceiveCompletion,// User Completion Routine
pSession, // User Completion Context
&pSession->m_pReceiveIoStatus,
pSession->m_pReceiveMdl,
0 // Flags
);
}
/////////////////////////////////////////////////////////////////////////////
// T D I E V E N T H A N D L E R S //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//// TCPS_DisconnectEventHandler (Session Event Handler)
//
// Purpose
//
// Parameters
// TdiEventContext - Pointer to TCPS_SESSION structure for the session.
//
// Return Value
//
// Remarks
// Disconnection indication prototype. This is invoked when a connection is
// being disconnected for a reason other than the user requesting it. Note
// that this is a change from TDI V1, which indicated only when the remote
// caused a disconnection. Any non-directed disconnection will cause this
// indication.
//
NTSTATUS TCPS_DisconnectEventHandler(
IN PVOID TdiEventContext, // Context From SetEventHandler
IN CONNECTION_CONTEXT ConnectionContext,
IN LONG DisconnectDataLength,
IN PVOID DisconnectData,
IN LONG DisconnectInformationLength,
IN PVOID DisconnectInformation,
IN ULONG DisconnectFlags
)
{
KdPrint(("TCPS_DisconnectEventHandler: Entry; EventContext: 0x%8.8X; ConnectionContext: 0x%8.8X; Flags: 0x%8.8X\n",
(ULONG )TdiEventContext, (ULONG)ConnectionContext, DisconnectFlags)
);
return( STATUS_SUCCESS );
}
/////////////////////////////////////////////////////////////////////////////
//// TCPS_ServerErrorEventHandler (Server Event Handler)
//
// Purpose
//
// Parameters
// TdiEventContext - Pointer to TCPS_SERVER structure for the server.
//
// Return Value
//
// Remarks
// A protocol error has occurred when this indication happens. This indication
// occurs only for errors of the worst type; the address this indication is
// delivered to is no longer usable for protocol-related operations, and
// should not be used for operations henceforth. All connections associated
// it are invalid.
// For NetBIOS-type providers, this indication is also delivered when a name
// in conflict or duplicate name occurs.
//
NTSTATUS TCPS_ServerErrorEventHandler(
IN PVOID TdiEventContext, // The endpoint's file object.
IN NTSTATUS Status // Status code indicating error type.
)
{
KdPrint(("TCPS_ServerErrorEventHandler: Status: 0x%8.8X\n", Status) );
return( STATUS_SUCCESS );
}
/////////////////////////////////////////////////////////////////////////////
//// TCPS_SessionErrorEventHandler (Server Event Handler)
//
// Purpose
//
// Parameters
// TdiEventContext - Pointer to TCPS_SERVER structure for the server.
//
// Return Value
//
// Remarks
// A protocol error has occurred when this indication happens. This indication
// occurs only for errors of the worst type; the address this indication is
// delivered to is no longer usable for protocol-related operations, and
// should not be used for operations henceforth. All connections associated
// it are invalid.
// For NetBIOS-type providers, this indication is also delivered when a name
// in conflict or duplicate name occurs.
//
NTSTATUS TCPS_SessionErrorEventHandler(
IN PVOID TdiEventContext, // The endpoint's file object.
IN NTSTATUS Status // Status code indicating error type.
)
{
KdPrint(("TCPS_SessionErrorEventHandler: Status: 0x%8.8X\n", Status) );
return( STATUS_SUCCESS );
}
/////////////////////////////////////////////////////////////////////////////
//// TCPS_ReceiveExpeditedEventHandler (Session Event Handler)
//
// Purpose
//
// Parameters
// TdiEventContext - Pointer to TCPS_SESSION structure for the session.
//
// Return Value
//
// Remarks
// This indication is delivered if expedited data is received on the connection.
// This will only occur in providers that support expedited data.
//
NTSTATUS TCPS_ReceiveExpeditedEventHandler(
IN PVOID TdiEventContext, // Context From SetEventHandler
IN CONNECTION_CONTEXT ConnectionContext,
IN ULONG ReceiveFlags, //
IN ULONG BytesIndicated, // number of bytes in this indication
IN ULONG BytesAvailable, // number of bytes in complete Tsdu
OUT ULONG *BytesTaken, // number of bytes used by indication routine
IN PVOID Tsdu, // pointer describing this TSDU, typically a lump of bytes
OUT PIRP *IoRequestPacket // TdiReceive IRP if MORE_PROCESSING_REQUIRED.
)
{
KdPrint(("TCPS_ReceiveExpeditedEventHandler: Entry...\n") );
KdPrint((" Bytes Indicated: %d; BytesAvailable: %d; Flags: 0x%8.8x\n",
BytesIndicated, BytesAvailable, ReceiveFlags));
return( STATUS_SUCCESS );
}
/////////////////////////////////////////////////////////////////////////////
//// TCPS_FreeSession
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
// Callers of TCPS_FreeSession must be running at IRQL PASSIVE_LEVEL.
//
VOID
TCPS_FreeSession(
PTCPS_SESSION pSession
)
{
ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
if( pSession )
{
KS_CloseConnectionEndpoint( &pSession->m_KS_Endpoint );
if( pSession->m_pListenIrp )
{
IoFreeIrp( pSession->m_pListenIrp );
}
if( pSession->m_pReceiveMdl )
{
KS_UnlockAndFreeMdl( pSession->m_pReceiveMdl );
}
pSession->m_pReceiveMdl = NULL;
if( pSession->m_pReceiveBuffer )
{
NdisFreeMemory(
pSession->m_pReceiveBuffer,
pSession->m_ReceiveBufferSize,
0
);
}
pSession->m_pReceiveBuffer = NULL;
NdisFreeMemory( pSession, sizeof( TCPS_SESSION ), 0 );
}
}
/////////////////////////////////////////////////////////////////////////////
//// TCPS_AllocateSession
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
// Callers of TCPS_AllocateSession must be running at IRQL PASSIVE_LEVEL.
//
NTSTATUS
TCPS_AllocateSession(
PTCPS_SERVER pServer,
PTCPS_SESSION *hSession
)
{
NTSTATUS Status;
PTCPS_SESSION pSession;
PDEVICE_OBJECT pDeviceObject;
ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
//
// Allocate Session Memory
//
Status = NdisAllocateMemory(
&pSession,
sizeof( TCPS_SESSION ),
0, // Allocate non-paged system-space memory
HighestAcceptableMax
);
if( !NT_SUCCESS( Status ) )
{
return( STATUS_INSUFFICIENT_RESOURCES );
}
NdisZeroMemory( pSession, sizeof( TCPS_SESSION ) );
pSession->m_pServer = pServer;
//
// Allocate The Receive Buffer
//
pSession->m_ReceiveBufferSize = (pSession->m_pServer)->m_TestParams.m_nBufferSize;
Status = NdisAllocateMemory(
&pSession->m_pReceiveBuffer,
pSession->m_ReceiveBufferSize,
0, // Allocate non-paged system-space memory
HighestAcceptableMax
);
if( !NT_SUCCESS( Status ) )
{
TCPS_FreeSession( pSession );
return( STATUS_INSUFFICIENT_RESOURCES );
}
NdisZeroMemory(
pSession->m_pReceiveBuffer,
pSession->m_ReceiveBufferSize
);
pSession->m_pReceiveMdl = KS_AllocateAndProbeMdl(
pSession->m_pReceiveBuffer, // Virtual Address
pSession->m_ReceiveBufferSize,
FALSE,
FALSE,
NULL
);
if( !pSession->m_pReceiveMdl )
{
TCPS_FreeSession( pSession );
return( STATUS_INSUFFICIENT_RESOURCES );
}
//
// Create The Connection Endpoint
//
Status = KS_OpenConnectionEndpoint(
TCP_DEVICE_NAME_W,
&pServer->m_KS_Address,
&pSession->m_KS_Endpoint,
&pSession->m_KS_Endpoint // Context
);
// BUGBUG!!! Resources Aren't Being Freed Systematically!!!
// Use TCPS_FreeSession....
if( !NT_SUCCESS( Status ) )
{
//
// Connection Endpoint Could Not Be Created
//
KS_CloseConnectionEndpoint( &pSession->m_KS_Endpoint );
NdisFreeMemory( pSession, sizeof( TCPS_SESSION ), 0 );
return( Status );
}
KdPrint(("TCPS_AllocateSession: Created Local TDI Connection Endpoint\n") );
pDeviceObject = IoGetRelatedDeviceObject(
pSession->m_KS_Endpoint.m_pFileObject
);
//
// Allocate Irp For Use In Listening For A Connection
//
pSession->m_pListenIrp = IoAllocateIrp(
pDeviceObject->StackSize,
FALSE
);
if( !pSession->m_pListenIrp )
{
KS_CloseConnectionEndpoint( &pSession->m_KS_Endpoint );
return( STATUS_INSUFFICIENT_RESOURCES );
}
//
// Build The Listen Request
//
pSession->m_RemoteConnectionInfo.UserDataLength = 0;
pSession->m_RemoteConnectionInfo.UserData = NULL;
pSession->m_RemoteConnectionInfo.OptionsLength = 0;
pSession->m_RemoteConnectionInfo.Options = NULL;
pSession->m_RemoteConnectionInfo.RemoteAddressLength = sizeof( TA_IP_ADDRESS );
pSession->m_RemoteConnectionInfo.RemoteAddress = &pSession->m_RemoteAddress;
//
// Start Listening On The Session
//
TdiBuildListen(
pSession->m_pListenIrp,
pDeviceObject,
pSession->m_KS_Endpoint.m_pFileObject,
TCPS_ConnectedCallback, // Completion Routine
pSession, // Completion Context
0, // Flags
NULL, // Request Connection Info
&pSession->m_RemoteConnectionInfo
);
Status = IoCallDriver( pDeviceObject, pSession->m_pListenIrp );
*hSession = pSession;
KdPrint(( "Created Session: 0x%8.8X\n", (ULONG )pSession ));
return( Status );
}
/////////////////////////////////////////////////////////////////////////////
//// TCPS_FreeSessionPool
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//
VOID
TCPS_FreeSessionPool(
PTCPS_SERVER pServer
)
{
PTCPS_SESSION pSession;
while( !IsListEmpty( &pServer->m_FreeSessionList ) )
{
pSession = (PTCPS_SESSION )RemoveHeadList( &pServer->m_FreeSessionList );
TCPS_FreeSession( pSession );
}
}
/////////////////////////////////////////////////////////////////////////////
//// TCPS_AllocateSessionPool
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -