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

📄 udpclient.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////////
//// INCLUDE FILES

#include "ndis.h"

#include "INetInc.h"
#include "TDITTCP.h"

// Copyright And Configuration Management ----------------------------------
//
//                Test (TTCP) Udp Server Device - UDPCLIENT.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 UDP 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;

#define  PATTERN_HEADER_SIZE 32


/////////////////////////////////////////////////////////////////////////////
//// LOCAL PROCEDURE PROTOTYPES


/////////////////////////////////////////////////////////////////////////////
//// LOCAL STRUCTURE DEFINITIONS

typedef
struct _UDPC_SESSION
{
   TDITTCP_TEST_PARAMS        m_TestParams;

   TA_IP_ADDRESS              m_LocalAddress;   // TDI Address

   TA_IP_ADDRESS              m_RemoteAddress;

   //
   // Local Address Object
   //
   KS_ADDRESS                 m_KS_Address;

   TDI_CONNECTION_INFORMATION m_RemoteConnectionInfo;

   ULONG                      m_PatternBufferSize;

   UCHAR                      m_pPatternHeaderBuffer[ PATTERN_HEADER_SIZE ];
   PMDL                       m_pPatternHeaderMdl;

   ULONG                      m_PatternDataBufferSize;
   PUCHAR                     m_pPatternDataBuffer;
   PMDL                       m_pPatternDataMdl;

   IO_STATUS_BLOCK            m_pPatternIoStatus;
   KEVENT                     m_FinalSendEvent;

   ULONG                      m_nNumBuffersToSend;

   PMDL                       m_pUdpGuardMdl;
   UCHAR                      m_UdpGuardBuffer[ UDP_GUARD_BUFFER_LENGTH ];

}
   UDPC_SESSION, *PUDPC_SESSION;


/////////////////////////////////////////////////////////////////////////////
//// UDPC_DeviceLoad
//
// Purpose
// This routine initializes the TDI TTCP UDP 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
UDPC_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(("UDPC_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 UDP Client Device
   //
   NdisInitUnicodeString(
      &UnicodeDeviceName,
      TDI_UDP_CLIENT_DEVICE_NAME_W
      );

   Status = IoCreateDevice(
               pDriverObject,
               sizeof(DEVICE_EXTENSION),
               &UnicodeDeviceName,
               FILE_DEVICE_UDP_CLIENT,
               0,            // Standard device characteristics
               FALSE,      // This isn't an exclusive device
               &pDeviceObject
               );

   if( !NT_SUCCESS( Status ) )
   {
      KdPrint(("UDPC_DeviceLoad: IoCreateDevice() failed:\n") );

      Status = STATUS_UNSUCCESSFUL;

      return(Status);
   }

   //
   // Create The TDI TTCP UDP 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] = UDPC_DeviceOpen;
   pDeviceExtension->MajorFunction[IRP_MJ_CLOSE]  = UDPC_DeviceClose;
   pDeviceExtension->MajorFunction[IRP_MJ_READ]   = NULL;
   pDeviceExtension->MajorFunction[IRP_MJ_WRITE]  = NULL;
   pDeviceExtension->MajorFunction[IRP_MJ_CLEANUP]  = UDPC_DeviceCleanup;
   pDeviceExtension->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = UDPC_DeviceIoControl;

   pDeviceExtension->DeviceUnload = UDPC_DeviceUnload;

   //
   // Fetch Transport Provider Information
   //
   Status = KS_QueryProviderInfo(
               UDP_DEVICE_NAME_W,
               &pDeviceExtension->UdpClientContext.TdiProviderInfo
               );

#ifdef DBG
   if (NT_SUCCESS(Status))
   {
      DEBUG_DumpProviderInfo(
         UDP_DEVICE_NAME_W,
         &pDeviceExtension->UdpClientContext.TdiProviderInfo );
   }
#endif // DBG

   return STATUS_SUCCESS;
}


/////////////////////////////////////////////////////////////////////////////
//// UDPC_DeviceOpen (IRP_MJ_CREATE Dispatch Routine)
//
// Purpose
// This is the dispatch routine for TDI TTCP UDP 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
UDPC_DeviceOpen(
    IN PDEVICE_OBJECT pDeviceObject,
    IN PIRP pIrp
    )
{
   PDEVICE_EXTENSION    pDeviceExtension;

   KdPrint(("UDPC_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( ("UDPC_DeviceOpen: Opened!!\n") );

   pIrp->IoStatus.Information = 0;

   TdiCompleteRequest( pIrp, STATUS_SUCCESS );

   return STATUS_SUCCESS;
}


/////////////////////////////////////////////////////////////////////////////
//// UDPC_DeviceClose (IRP_MJ_CLOSE Dispatch Routine)
//
// Purpose
// This is the dispatch routine for TDI TTCP UDP Client device close requests.
//
// Parameters
//    pDeviceObject - Pointer to the device object.
//    pIrp - Pointer to the request packet.
//
// Return Value
// Status is returned.
//
// Remarks
//

NTSTATUS
UDPC_DeviceClose(
    IN PDEVICE_OBJECT pDeviceObject,
    IN PIRP pIrp
    )
{
   PDEVICE_EXTENSION    pDeviceExtension;

   KdPrint(("UDPC_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( ("UDPC_DeviceClose: Closed!!\n") );

   pIrp->IoStatus.Information = 0;

   TdiCompleteRequest( pIrp, STATUS_SUCCESS );

   return STATUS_SUCCESS;
}


/////////////////////////////////////////////////////////////////////////////
//// UDPC_ErrorEventHandler
//
// Purpose
//
// Parameters
//
// 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 UDPC_ErrorEventHandler(
   IN PVOID TdiEventContext,  // The endpoint's file object.
   IN NTSTATUS Status         // Status code indicating error type.
   )
{
   KdPrint(("UDPC_ErrorEventHandler: Status: 0x%8.8X\n", Status) );

   return( STATUS_SUCCESS );
}


/////////////////////////////////////////////////////////////////////////////
//// UDPC_ReceiveDatagramEventHandler
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
// TDI_IND_RECEIVE_DATAGRAM indication handler definition.  This client
// routine is called by the transport provider when a connectionless TSDU
// is received that should be presented to the client.
//

NTSTATUS
UDPC_ReceiveDatagramEventHandler(
   IN PVOID TdiEventContext,     // Context From SetEventHandler
   IN LONG SourceAddressLength,    // length of the originator of the datagram
   IN PVOID SourceAddress,         // string describing the originator of the datagram
   IN LONG OptionsLength,          // options for the receive
   IN PVOID Options,               //
   IN ULONG ReceiveDatagramFlags,  //
   IN ULONG BytesIndicated,
   IN ULONG BytesAvailable,
   OUT ULONG *BytesTaken,
   IN PVOID Tsdu,				// pointer describing this TSDU, typically a lump of bytes
   OUT PIRP *IoRequestPacket	// TdiReceive IRP if MORE_PROCESSING_REQUIRED.
   )
{
   KdPrint(("UDPC_ReceiveDatagramEventHandler: Entry...\n") );

   KdPrint(("  Bytes Indicated: %d; BytesAvailable: %d; Flags: 0x%8.8x\n",
      BytesIndicated, BytesAvailable, ReceiveDatagramFlags));

   return( STATUS_SUCCESS );
}

NTSTATUS
UDPC_SendGuardBuffer(
   PUDPC_SESSION  pSession
   )
{
   NTSTATUS Status;

   (pSession->m_pUdpGuardMdl)->Next = NULL;   // IMPORTANT!!!

   Status = KS_SendDatagramOnAddress(
                  &pSession->m_KS_Address,
                  NULL,       // User Completion Event
                  NULL,       // User Completion Routine
                  NULL,       // User Completion Context
                  &pSession->m_pPatternIoStatus,
                  pSession->m_pUdpGuardMdl,
                  &pSession->m_RemoteConnectionInfo
                  );

   if( NT_SUCCESS(Status) )
   {
      KdPrint(( "UDPC_SendGuardBuffer: Status 0x%8.8X\n", pSession->m_pPatternIoStatus.Status ));
      KdPrint(( "UDPC_SendGuardBuffer: Sent %d Bytes\n", pSession->m_pPatternIoStatus.Information ));
   }
   else
   {
      KdPrint(( "UDPC_SendGuardBuffer: Status 0x%8.8X\n", Status ));
   }

   return( Status );
}

/////////////////////////////////////////////////////////////////////////////
//// UDPC_TestThread
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//

VOID
UDPC_TestThread(
   IN PVOID pContext
   )
{
   NTSTATUS             Status = STATUS_SUCCESS;
   NDIS_STATUS          nNdisStatus;
   PTTCP_TEST_START_CMD pStartCmd = NULL;
   PUDPC_SESSION        pSession = (PUDPC_SESSION )pContext;
   LARGE_INTEGER        DelayTime;

   KdPrint(("UDPC_TestThread: Starting...\n") );

   //
   // Initialize Default Settings
   //
   Status = STATUS_SUCCESS;      // Always Indicate I/O Success

   //
   // Locate Test Session Parameter Buffer
   //
   pSession = (PUDPC_SESSION )pContext;

   pSession->m_PatternBufferSize = pSession->m_TestParams.m_nBufferSize;
   pSession->m_nNumBuffersToSend = pSession->m_TestParams.m_nNumBuffersToSend;

   //
   // Force Size To Allow Send Buffer Chaining Demonstration
   //
   if( pSession->m_PatternBufferSize < 64 )
   {
      pSession->m_PatternBufferSize = 64;
   }

   pSession->m_PatternDataBufferSize = pSession->m_PatternBufferSize - PATTERN_HEADER_SIZE;

   //
   // Allocate The Pattern Header MDL
   //
   RtlFillMemory( 
      pSession->m_pPatternHeaderBuffer,
      PATTERN_HEADER_SIZE,
      'X'
      );

   pSession->m_pPatternHeaderMdl = KS_AllocateAndProbeMdl(
                              pSession->m_pPatternHeaderBuffer,   // Virtual Address
                              PATTERN_HEADER_SIZE,
                              FALSE,
                              FALSE,
                              NULL
                              );

   if( !pSession->m_pPatternHeaderMdl )
   {
      goto ExitTheThread;
   }

   //
   // Allocate The Pattern Data Buffer
   //
   nNdisStatus = NdisAllocateMemory(
                  &pSession->m_pPatternDataBuffer,
                  pSession->m_PatternDataBufferSize,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -