📄 tcpclient.c
字号:
/////////////////////////////////////////////////////////////////////////////
//// INCLUDE FILES
#include "ndis.h"
#include "TDI.H"
#include "TDIKRNL.H"
#include "KSUtil.h"
#include "INetInc.h"
#include "TDITTCP.h"
// Copyright And Configuration Management ----------------------------------
//
// TDI Test (TTCP) Tcp Server Device - TCPLCIENT.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 Client 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;
/////////////////////////////////////////////////////////////////////////////
//// LOCAL PROCEDURE PROTOTYPES
/////////////////////////////////////////////////////////////////////////////
//// LOCAL STRUCTURE DEFINITIONS
typedef
struct _TCPC_SESSION
{
TDITTCP_TEST_PARAMS m_TestParams;
TA_IP_ADDRESS m_LocalAddress; // TDI Address
KS_ADDRESS m_KS_Address;
//
// 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;
UCHAR m_InfoBuffer[ 256 ];
ULONG m_PatternBufferSize;
PUCHAR m_pPatternBuffer;
PMDL m_pPatternMdl;
IO_STATUS_BLOCK m_PatternIoStatus;
KEVENT m_FinalSendEvent;
ULONG m_nNumBuffersToSend;
}
TCPC_SESSION, *PTCPC_SESSION;
/////////////////////////////////////////////////////////////////////////////
//// TCPC_DeviceLoad
//
// Purpose
// This routine initializes the TDI TTCP TCP Client 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
TCPC_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(("TCPC_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 Client Device
//
NdisInitUnicodeString(
&UnicodeDeviceName,
TDI_TCP_CLIENT_DEVICE_NAME_W
);
Status = IoCreateDevice(
pDriverObject,
sizeof(DEVICE_EXTENSION),
&UnicodeDeviceName,
FILE_DEVICE_TCP_CLIENT,
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 Client 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] = TCPC_DeviceOpen;
pDeviceExtension->MajorFunction[IRP_MJ_CLOSE] = TCPC_DeviceClose;
pDeviceExtension->MajorFunction[IRP_MJ_READ] = NULL;
pDeviceExtension->MajorFunction[IRP_MJ_WRITE] = NULL;
pDeviceExtension->MajorFunction[IRP_MJ_CLEANUP] = TCPC_DeviceCleanup;
pDeviceExtension->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TCPC_DeviceIoControl;
pDeviceExtension->DeviceUnload = TCPC_DeviceUnload;
//
// Fetch Transport Provider Information
//
Status = KS_QueryProviderInfo(
TCP_DEVICE_NAME_W,
&pDeviceExtension->TcpClientContext.TdiProviderInfo
);
#ifdef DBG
if (NT_SUCCESS(Status))
{
DEBUG_DumpProviderInfo(
TCP_DEVICE_NAME_W,
&pDeviceExtension->TcpClientContext.TdiProviderInfo
);
}
#endif // DBG
return STATUS_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////
//// TCPC_DeviceOpen (IRP_MJ_CREATE Dispatch Routine)
//
// Purpose
// This is the dispatch routine for TDI TTCP TCP Client device create/open
// requests.
//
// Parameters
// pDeviceObject - Pointer to the device object.
// pIrp - Pointer to the request packet.
//
// Return Value
// Status is returned.
//
// Remarks
//
NTSTATUS
TCPC_DeviceOpen(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp
)
{
PDEVICE_EXTENSION pDeviceExtension;
KdPrint(("TCPC_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( ("TCPC_DeviceOpen: Opened!!\n") );
pIrp->IoStatus.Information = 0;
TdiCompleteRequest( pIrp, STATUS_SUCCESS );
return STATUS_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////
//// TCPC_DeviceClose (IRP_MJ_CLOSE Dispatch Routine)
//
// Purpose
// This is the dispatch routine for TDI TTCP TCP Client device close requests.
//
// Parameters
// pDeviceObject - Pointer to the device object.
// pIrp - Pointer to the request packet.
//
// Return Value
// Status is returned.
//
// Remarks
//
NTSTATUS
TCPC_DeviceClose(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp
)
{
PDEVICE_EXTENSION pDeviceExtension;
KdPrint(("TCPC_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( ("TCPC_DeviceClose: Closed!!\n") );
pIrp->IoStatus.Information = 0;
TdiCompleteRequest( pIrp, STATUS_SUCCESS );
return STATUS_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////
// T D I E V E N T H A N D L E R S //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//// TCPC_DisconnectEventHandler
//
// Purpose
//
// Parameters
// TdiEventContext - Pointer to TCPC_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 TCPC_DisconnectEventHandler(
IN PVOID TdiEventContext, // Context From SetEventHandler
IN CONNECTION_CONTEXT ConnectionContext, // As passed to TdiOpenConnection
IN LONG DisconnectDataLength,
IN PVOID DisconnectData,
IN LONG DisconnectInformationLength,
IN PVOID DisconnectInformation,
IN ULONG DisconnectFlags
)
{
KdPrint(("TCPC_DisconnectEventHandler: Entry; EventContext: 0x%8.8X; ConnectionContext: 0x%8.8X; Flags: 0x%8.8X\n",
(ULONG )TdiEventContext, (ULONG)ConnectionContext, DisconnectFlags)
);
return( STATUS_SUCCESS );
}
/////////////////////////////////////////////////////////////////////////////
//// TCPC_ErrorEventHandler
//
// Purpose
//
// Parameters
// TdiEventContext - Pointer to TCPC_SESSION structure for the session.
//
// 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.
//
NTSTATUS TCPC_ErrorEventHandler(
IN PVOID TdiEventContext, // The endpoint's file object.
IN NTSTATUS Status // Status code indicating error type.
)
{
KdPrint(("TCPC_ErrorEventHandler: Status: 0x%8.8X\n", Status) );
return( STATUS_SUCCESS );
}
/////////////////////////////////////////////////////////////////////////////
//// TCPC_ReceiveEventHandler
//
// Purpose
//
// Parameters
// TdiEventContext - Pointer to TCPC_SESSION structure for the session.
//
// Return Value
//
// Remarks
// TDI_IND_RECEIVE indication handler definition. This client routine is
// called by the transport provider when a connection-oriented TSDU is received
// that should be presented to the client.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -