📄 tcpserver.c
字号:
/////////////////////////////////////////////////////////////////////////////
//// INCLUDE FILES
#include "ndis.h"
#include "INetInc.h"
#include "TDITTCP.h"
// Copyright And Configuration Management ----------------------------------
//
// TDI Test (TTCP) Tcp Server Device - TCPSERVER.c
//
// PCAUSA TDI Client Samples For Windows NT
//
// Copyright (c) 1999-2000 Printing Communications Associates, Inc.
// - PCAUSA -
//
// Thomas F. Divine
// 4201 Brunswick Court
// Smyrna, Georgia 30080 USA
// (770) 432-4580
// tdivine@pcausa.com
//
// End ---------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
//// TDI TTCP TCP Server GLOBAL DATA
//
// Some developers have suggested that the gollowing g_ data should
// be placed in the DeviceExtension instead of simply being "ordinary"
// global data.
//
// DeviceExtension memory allocated from the non-paged pool. Device driver
// global memory is also allocated from the non-paged pool - UNLESS you
// use #pragma directives to cause it to be allocated from the paged pool.
//
// In this driver, use of global memory is safe enough...
//
static BOOLEAN g_bSymbolicLinkCreated = FALSE;
static LIST_ENTRY g_TCPServerList;
static KEVENT g_TCPS_KillEvent;
/////////////////////////////////////////////////////////////////////////////
//// LOCAL STRUCTURE DEFINITIONS
typedef
struct _TCPS_SERVER
{
LIST_ENTRY m_ListElement;
HANDLE m_hTestThread;
TDITTCP_TEST_PARAMS m_TestParams;
TA_IP_ADDRESS m_LocalAddress; // TDI Address
KS_ADDRESS m_KS_Address;
LIST_ENTRY m_ActiveSessionList;
LIST_ENTRY m_FreeSessionList;
}
TCPS_SERVER, *PTCPS_SERVER;
typedef
struct _TCPS_SESSION
{
LIST_ENTRY m_ListElement;
PTCPS_SERVER m_pServer; // Parent Server
//
// Local Connection Endpoint
// -------------------------
// The KS_ENDPOINT structure contains information that defines:
// TDI Address Object
// TDI Connection Context
//
// Together these two objects represent the local connection endpoint.
//
KS_ENDPOINT m_KS_Endpoint;
TA_IP_ADDRESS m_RemoteAddress;
TDI_CONNECTION_INFORMATION m_RemoteConnectionInfo;
ULONG m_ReceiveBufferSize;
PUCHAR m_pReceiveBuffer;
PMDL m_pReceiveMdl;
IO_STATUS_BLOCK m_pReceiveIoStatus;
PIRP m_pListenIrp;
ULONG m_nBytesReceived;
}
TCPS_SESSION, *PTCPS_SESSION;
/////////////////////////////////////////////////////////////////////////////
//// LOCAL PROCEDURE PROTOTYPES
NTSTATUS
TCPS_AllocateSession(
PTCPS_SERVER pServer,
PTCPS_SESSION *hSession
);
VOID
TCPS_FreeSession(
PTCPS_SESSION pSession
);
VOID
TCPS_ReceiveCompletion(
PVOID UserCompletionContext,
PIO_STATUS_BLOCK IoStatusBlock,
ULONG Reserved
);
/////////////////////////////////////////////////////////////////////////////
//// TCPS_DeviceLoad
//
// Purpose
// This routine initializes the TDI TTCP TCP Server device.
//
// Parameters
// pDriverObject - Pointer to driver object created by system.
// RegistryPath - Pointer to the Unicode name of the registry path
// for this driver.
//
// Return Value
// The function return value is the final status from the initialization
// operation.
//
// Remarks
//
NTSTATUS
TCPS_DeviceLoad(
IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING RegistryPath
)
{
UNICODE_STRING UnicodeDeviceName;
PDEVICE_OBJECT pDeviceObject = NULL;
PDEVICE_EXTENSION pDeviceExtension = NULL;
NTSTATUS Status = STATUS_SUCCESS;
NTSTATUS ErrorCode = STATUS_SUCCESS;
KdPrint(("TCPS_DeviceLoad: Entry...\n") );
//
// Initialize Global Data
//
//
// Set up the driver's device entry points.
//
pDriverObject->MajorFunction[IRP_MJ_CREATE] = TDITTCPDeviceOpen;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = TDITTCPDeviceClose;
pDriverObject->MajorFunction[IRP_MJ_READ] = TDITTCPDeviceRead;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = TDITTCPDeviceWrite;
pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = TDITTCPDeviceCleanup;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TDITTCPDeviceIoControl;
pDriverObject->DriverUnload = TDITTCPDriverUnload;
//
// Create The TDI TTCP TCP Server Device
//
NdisInitUnicodeString(
&UnicodeDeviceName,
TDI_TCP_SERVER_DEVICE_NAME_W
);
Status = IoCreateDevice(
pDriverObject,
sizeof(DEVICE_EXTENSION),
&UnicodeDeviceName,
FILE_DEVICE_TCP_SERVER,
0, // Standard device characteristics
FALSE, // This isn't an exclusive device
&pDeviceObject
);
if( !NT_SUCCESS( Status ) )
{
KdPrint(("TDITTCP: IoCreateDevice() failed:\n") );
Status = STATUS_UNSUCCESSFUL;
return(Status);
}
//
// Create The TDI TTCP TCP Server Device Symbolic Link
//
Status = KS_CreateSymbolicLink(
&UnicodeDeviceName,
TRUE
);
if( NT_SUCCESS (Status ) )
{
g_bSymbolicLinkCreated = TRUE;
}
pDeviceObject->Flags |= DO_DIRECT_IO; // Effects Read/Write Only...
//
// Initialize The Device Extension
//
pDeviceExtension = (PDEVICE_EXTENSION)pDeviceObject->DeviceExtension;
RtlZeroMemory( pDeviceExtension, sizeof(DEVICE_EXTENSION) );
pDeviceExtension->pDeviceObject = pDeviceObject;
//
// Setup The Driver Device Entry Points
//
pDeviceExtension->MajorFunction[IRP_MJ_CREATE] = TCPS_DeviceOpen;
pDeviceExtension->MajorFunction[IRP_MJ_CLOSE] = TCPS_DeviceClose;
pDeviceExtension->MajorFunction[IRP_MJ_READ] = NULL;
pDeviceExtension->MajorFunction[IRP_MJ_WRITE] = NULL;
pDeviceExtension->MajorFunction[IRP_MJ_CLEANUP] = TCPS_DeviceCleanup;
pDeviceExtension->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TCPS_DeviceIoControl;
pDeviceExtension->DeviceUnload = TCPS_DeviceUnload;
//
// Fetch Transport Provider Information
//
Status = KS_QueryProviderInfo(
TCP_DEVICE_NAME_W,
&pDeviceExtension->TcpServerContext.TdiProviderInfo
);
#ifdef DBG
if (NT_SUCCESS(Status))
{
DEBUG_DumpProviderInfo(
TCP_DEVICE_NAME_W,
&pDeviceExtension->TcpServerContext.TdiProviderInfo
);
}
#endif // DBG
InitializeListHead( &g_TCPServerList );
//
// Initialize The Sever Kill Event
//
KeInitializeEvent(
&g_TCPS_KillEvent,
NotificationEvent,
FALSE
);
return STATUS_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////
//// TCPS_DeviceOpen (IRP_MJ_CREATE Dispatch Routine)
//
// Purpose
// This is the dispatch routine for TDI TTCP TCP Server device create/open
// requests.
//
// Parameters
// pDeviceObject - Pointer to the device object.
// pIrp - Pointer to the request packet.
//
// Return Value
// Status is returned.
//
// Remarks
//
NTSTATUS
TCPS_DeviceOpen(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp
)
{
PDEVICE_EXTENSION pDeviceExtension;
KdPrint(("TCPS_DeviceOpen: Entry...\n") );
pDeviceExtension = pDeviceObject->DeviceExtension;
//
// No need to do anything.
//
//
// Fill these in before calling IoCompleteRequest.
//
// DON'T get cute and try to use the status field of
// the irp in the return status. That IRP IS GONE as
// soon as you call IoCompleteRequest.
//
KdPrint( ("TCPS_DeviceOpen: Opened!!\n") );
pIrp->IoStatus.Information = 0;
TdiCompleteRequest( pIrp, STATUS_SUCCESS );
return STATUS_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////
//// TCPS_DeviceClose (IRP_MJ_CLOSE Dispatch Routine)
//
// Purpose
// This is the dispatch routine for TDI TTCP TCP Server device close requests.
//
// Parameters
// pDeviceObject - Pointer to the device object.
// pIrp - Pointer to the request packet.
//
// Return Value
// Status is returned.
//
// Remarks
//
NTSTATUS
TCPS_DeviceClose(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp
)
{
PDEVICE_EXTENSION pDeviceExtension;
KdPrint(("TCPS_DeviceClose: Entry...\n") );
pDeviceExtension = pDeviceObject->DeviceExtension;
//
// No need to do anything.
//
//
// Fill these in before calling IoCompleteRequest.
//
// DON'T get cute and try to use the status field of
// the irp in the return status. That IRP IS GONE as
// soon as you call IoCompleteRequest.
//
KdPrint( ("TCPS_DeviceClose: Closed!!\n") );
pIrp->IoStatus.Information = 0;
TdiCompleteRequest( pIrp, STATUS_SUCCESS );
return STATUS_SUCCESS;
}
NTSTATUS
TCPS_ConnectedCallback(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp,
IN PVOID Context
)
{
PTCPS_SESSION pSession = (PTCPS_SESSION)Context;
PTCPS_SERVER pServer = pSession->m_pServer;
NTSTATUS Status = pIrp->IoStatus.Status;
KdPrint(( "TCPS_ConnectedCallback: FinalStatus: 0x%8.8x\n", Status ));
RemoveEntryList( &pSession->m_ListElement );
if( NT_SUCCESS( Status ) )
{
#if DBG
DEBUG_DumpTransportAddress(
(PTRANSPORT_ADDRESS )&pSession->m_RemoteAddress
);
#endif
//
// Start The First Receive
//
pSession->m_nBytesReceived = 0;
//
// Start The First Receive On The Session
//
(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
);
}
return( STATUS_MORE_PROCESSING_REQUIRED );
}
VOID
TCPS_DisconnectCallback(
PVOID UserCompletionContext,
PIO_STATUS_BLOCK IoStatusBlock,
ULONG Reserved
)
{
PTCPS_SESSION pSession = (PTCPS_SESSION)UserCompletionContext;
PTCPS_SERVER pServer = pSession->m_pServer;
NTSTATUS Status = IoStatusBlock->Status;
PDEVICE_OBJECT pDeviceObject;
KdPrint(( "TCPS_DisconnectCallback: FinalStatus: 0x%8.8x\n", Status ));
//
// Start Another Listen On The Session
//
// ATTENTION!!! Check For Shutdown Status!!!
pDeviceObject = IoGetRelatedDeviceObject(
pSession->m_KS_Endpoint.m_pFileObject
);
TdiBuildListen(
pSession->m_pListenIrp,
pDeviceObject,
pSession->m_KS_Endpoint.m_pFileObject,
TCPS_ConnectedCallback, // Completion Routine
pSession, // Completion Context
0, // Flags
// TDI_QUERY_ACCEPT, // Flags
NULL, // Request Connection Info
&pSession->m_RemoteConnectionInfo
);
Status = IoCallDriver( pDeviceObject, pSession->m_pListenIrp );
//
// Add The Session To The Free Session List
//
InsertTailList(
&pServer->m_FreeSessionList,
&pSession->m_ListElement
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -