⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcpserver.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 3 页
字号:
/////////////////////////////////////////////////////////////////////////////
//// 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 + -