📄 tcpserver.c
字号:
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//
NTSTATUS
TCPS_AllocateSessionPool(
PTCPS_SERVER pServer,
INT nNumberOfSessions // Number Of Sessions To Allocate
)
{
PTCPS_SESSION pSession;
NTSTATUS Status;
INT i, NumAllocated = 0;
for( i = 0; i < nNumberOfSessions; ++i )
{
Status = TCPS_AllocateSession(
pServer,
&pSession
);
if( !NT_SUCCESS( Status ) )
{
break;
}
//
// Add The Session To The Free Session List
//
InsertTailList(
&pServer->m_FreeSessionList,
&pSession->m_ListElement
);
++NumAllocated;
}
return( NumAllocated > 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL );
}
/////////////////////////////////////////////////////////////////////////////
//// TCPS_TestThread
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//
VOID
TCPS_TestThread(
IN PVOID pContext
)
{
NTSTATUS Status = STATUS_SUCCESS;
NDIS_STATUS nNdisStatus;
PTTCP_TEST_START_CMD pStartCmd = NULL;
PTCPS_SERVER pServer = (PTCPS_SERVER )pContext;
LARGE_INTEGER DelayTime;
KdPrint(("TCPS_TestThread: Starting...\n") );
//
// Initialize Default Settings
//
Status = STATUS_SUCCESS; // Always Indicate I/O Success
//
// Locate Test Session Parameter Buffer
//
pServer = (PTCPS_SERVER )pContext;
//
// Perform Additional Initialization Of TCPS_SERVER Structure
//
InitializeListHead( &pServer->m_ActiveSessionList );
InitializeListHead( &pServer->m_FreeSessionList );
//
// Setup Local TDI Address
//
KS_InitIPAddress(
&pServer->m_LocalAddress,
INADDR_ANY, // Any Local Address
pServer->m_TestParams.m_Port // Specific Port
);
//
// Open Transport Address
//
Status = KS_OpenTransportAddress(
TCP_DEVICE_NAME_W,
(PTRANSPORT_ADDRESS )&pServer->m_LocalAddress,
&pServer->m_KS_Address
);
if( !NT_SUCCESS( Status ) )
{
//
// Address Object Could Not Be Created
//
goto ExitTheThread;
}
//
// Setup Event Handlers On The Server Address Object
//
Status = KS_SetEventHandlers(
&pServer->m_KS_Address,
pServer, // Event Context
NULL, // ConnectEventHandler
TCPS_DisconnectEventHandler,
TCPS_SessionErrorEventHandler,
NULL, // ReceiveEventHandler,
NULL, // ReceiveDatagramEventHandler
TCPS_ReceiveExpeditedEventHandler
);
if( !NT_SUCCESS( Status ) )
{
//
// Event Handlers Could Not Be Set
//
goto ExitTheThread;
}
KdPrint(("TCPS_TestThread: Set Event Handlers On The Server Address Object\n") );
//
// Allocate Free Sessions, Used To Accept Connections
//
// Status = TCPS_AllocateSessionPool( pServer, 4 );
Status = TCPS_AllocateSessionPool( pServer, 1 );
if( !NT_SUCCESS( Status ) )
{
goto ExitTheThread;
}
KdPrint(("TCPS_TestThread: Session Pool Allocated\n") );
//
// Add The Server To The Active Server List
//
InsertTailList(
&g_TCPServerList,
&pServer->m_ListElement
);
Status = KeWaitForSingleObject(
&g_TCPS_KillEvent, // Object to wait on.
Executive, // Reason for waiting
KernelMode, // Processor mode
FALSE, // Alertable
NULL // Timeout
);
//
// ATTENTION!!! Test Exit...
//
KdPrint(( "Waiting After Disconnect...\n" ));
DelayTime.QuadPart = 10*1000*1000*5; // 5 Seconds
KeDelayExecutionThread( KernelMode, FALSE, &DelayTime );
//
// Exit The Thread
//
ExitTheThread:
KdPrint(("TCPS_TestThread: Exiting...\n") );
RemoveEntryList( &pServer->m_ListElement );
//
// Close Active Sessions
//
//
// Free The Free Session Pool
//
ASSERT( IsListEmpty( &pServer->m_ActiveSessionList ) );
TCPS_FreeSessionPool( pServer );
ASSERT( IsListEmpty( &pServer->m_FreeSessionList ) );
//
// Close The Transport Address
//
KS_CloseTransportAddress( &pServer->m_KS_Address );
NdisFreeMemory( pServer, sizeof( TCPS_SERVER ), 0 );
(void)PsTerminateSystemThread( STATUS_SUCCESS );
}
/////////////////////////////////////////////////////////////////////////////
//// TCPS_StartTest
//
// Purpose
// Start A TTCP TCP Server Test
//
// Parameters
// pDeviceObject - Pointer to the device object.
// pIrp - Pointer to the request packet.
//
// Return Value
// Status is returned.
//
// Remarks
//
NTSTATUS
TCPS_StartTest(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp
)
{
NDIS_STATUS nNdisStatus;
PTTCP_TEST_START_CMD pStartCmd = NULL;
PTCPS_SERVER pServer = NULL;
//
// Initialize Default Settings
//
pIrp->IoStatus.Information = sizeof( ULONG ); // For m_Status
//
// Locate Test Start Command Buffer
//
pStartCmd = (PTTCP_TEST_START_CMD )pIrp->AssociatedIrp.SystemBuffer;
pStartCmd->m_Status = STATUS_UNSUCCESSFUL;
TDITTCP_DumpTestParams( &pStartCmd->m_TestParams );
//
// Allocate Memory For The Test Session
//
nNdisStatus = NdisAllocateMemory(
&pServer,
sizeof( TCPS_SERVER ),
0, // Allocate non-paged system-space memory
HighestAcceptableMax
);
if( !NT_SUCCESS( nNdisStatus ) )
{
return( nNdisStatus );
}
NdisZeroMemory( pServer, sizeof( TCPS_SERVER ) );
NdisMoveMemory(
&pServer->m_TestParams,
&pStartCmd->m_TestParams,
sizeof( TDITTCP_TEST_PARAMS )
);
//
// Start The Thread That Will Execute The Test
//
PsCreateSystemThread(
&pServer->m_hTestThread, // thread handle
0L, // desired access
NULL, // object attributes
NULL, // process handle
NULL, // client id
TCPS_TestThread, // start routine
(PVOID )pServer // start context
);
return( STATUS_SUCCESS );
}
/////////////////////////////////////////////////////////////////////////////
//// TCPS_DeviceIoControl (IRP_MJ_DEVICE_CONTROL Dispatch Routine)
//
// Purpose
// This is the dispatch routine for TDI TTCP TCP Server device IOCTL requests.
//
// Parameters
// pDeviceObject - Pointer to the device object.
// pIrp - Pointer to the request packet.
//
// Return Value
// Status is returned.
//
// Remarks
//
NTSTATUS
TCPS_DeviceIoControl(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp
)
{
PDEVICE_EXTENSION pDeviceExtension;
NTSTATUS Status;
PIO_STACK_LOCATION pIrpSp;
ULONG nFunctionCode;
KdPrint(("TCPS_DeviceIoControl: Entry...\n") );
pDeviceExtension = pDeviceObject->DeviceExtension;
pIrp->IoStatus.Information = 0; // Nothing Returned Yet
pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
nFunctionCode=pIrpSp->Parameters.DeviceIoControl.IoControlCode;
switch( nFunctionCode )
{
case IOCTL_TCP_SERVER_START_TEST:
Status = TCPS_StartTest( pDeviceObject, pIrp );
break;
default:
KdPrint(( "FunctionCode: 0x%8.8X\n", nFunctionCode ));
Status = STATUS_UNSUCCESSFUL;
break;
}
TdiCompleteRequest( pIrp, Status );
return( Status );
}
/////////////////////////////////////////////////////////////////////////////
//// TCPS_DeviceCleanup (IRP_MJ_CLEANUP Dispatch Routine)
//
// Purpose
// This is the dispatch routine for TDI TTCP TCP Server device cleanup
// requests.
//
// Parameters
// pDeviceObject - Pointer to the device object.
// pFlushIrp - Pointer to the flush request packet.
//
// Return Value
// Status is returned.
//
// Remarks
//
NTSTATUS
TCPS_DeviceCleanup(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp
)
{
PDEVICE_EXTENSION pDeviceExtension;
KdPrint(("TCPS_DeviceCleanup: Entry...\n"));
pDeviceExtension = pDeviceObject->DeviceExtension;
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
return( STATUS_SUCCESS );
}
/////////////////////////////////////////////////////////////////////////////
//// TCPS_DeviceUnload
//
// Purpose
//
// Parameters
// pDeviceObject - Pointer to device object created by system.
//
// Return Value
//
// Remarks
//
VOID
TCPS_DeviceUnload(
IN PDEVICE_OBJECT pDeviceObject
)
{
PDEVICE_EXTENSION pDeviceExtension;
PTCPS_SERVER pServer = NULL;
KEVENT TCPS_UnloadEvent;
LARGE_INTEGER UnloadWait;
NTSTATUS Status;
KdPrint(("TCPS_DeviceUnload: Entry...\n") );
pDeviceExtension = pDeviceObject->DeviceExtension;
KeSetEvent( &g_TCPS_KillEvent, 0, FALSE);
//
// Initialize The Sever Unload Event
//
KeInitializeEvent(
&TCPS_UnloadEvent,
NotificationEvent,
FALSE
);
while( !IsListEmpty( &g_TCPServerList ) )
{
// UnloadWait.QuadPart = -(10 * 1000 * 3000);
UnloadWait.QuadPart = -(10 * 1000 * 3000);
Status = KeWaitForSingleObject(
&TCPS_UnloadEvent, // Object to wait on.
Executive, // Reason for waiting
KernelMode, // Processor mode
FALSE, // Alertable
&UnloadWait // Timeout
);
}
//
// Destroy The Symbolic Link
//
if( g_bSymbolicLinkCreated )
{
UNICODE_STRING UnicodeDeviceName;
NdisInitUnicodeString(
&UnicodeDeviceName,
TDI_TCP_SERVER_DEVICE_NAME_W
);
KS_CreateSymbolicLink(
&UnicodeDeviceName,
FALSE
);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -