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

📄 kstcpex.c

📁 网络驱动开发
💻 C
字号:
/////////////////////////////////////////////////////////////////////////////
//// INCLUDE FILES

#include	"NDIS.H"
#include	"TDI.H"
#include	"TDIKRNL.H"
#include "KSUtil.h"

// Copyright And Configuration Management ----------------------------------
//
//                  TCP Extension IOCTL Support - KSTcpEx.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 ---------------------------------------------------------------------

/////////////////////////////////////////////////////////////////////////////
//// NOTES
//
//

/////////////////////////////////////////////////////////////////////////////
//// STRUCTURES

#define TL_INSTANCE 0


/////////////////////////////////////////////////////////////////////////////
//                                                                         //
/////////////////////////////////////////////////////////////////////////////

//
// ATTENTION!!!
// ------------
// Extend to support setting:
//
//   TCP-Level Options
//   UDP-Level Options
//   IP-Level Options
//   Socket-Level Options
//
// Account for the fact that some options must be set on Address file
// objects and others must be set on Connection file objects.
//
//

NTSTATUS
KS_TCPSetInformation(
   PFILE_OBJECT   pFileObject,
   ULONG          Entity,
   ULONG          Class,
   ULONG          Type,
   ULONG          Id,
   PVOID          pValue,
   ULONG          ValueLength
   )
{
   PIRP                 pIrp;
   IO_STATUS_BLOCK      IoStatus;
   PIO_STACK_LOCATION   pIrpSp;
   KEVENT               SyncEvent;
   NTSTATUS             Status;
   PTCP_REQUEST_SET_INFORMATION_EX pSetInfoEx;
   ULONG                Length;
   PDEVICE_OBJECT       pDeviceObject;

   //
   // Allocate Memory For Private Completion Context
   //
   Length = sizeof( TCP_REQUEST_SET_INFORMATION_EX ) + ValueLength;

   Status = NdisAllocateMemory(
                  &pSetInfoEx,
                  Length + sizeof( ULONG ),
                  0,       // Allocate non-paged system-space memory
                  HighestAcceptableMax
                  );

   if( !NT_SUCCESS( Status ) )
   {
      return( STATUS_INSUFFICIENT_RESOURCES );
   }

   pSetInfoEx->ID.toi_entity.tei_entity = Entity;
   pSetInfoEx->ID.toi_entity.tei_instance = TL_INSTANCE;
   pSetInfoEx->ID.toi_class = Class;
   pSetInfoEx->ID.toi_type = Type;
   pSetInfoEx->ID.toi_id = Id;

   NdisMoveMemory( pSetInfoEx->Buffer, (PUCHAR )pValue, ValueLength );
   pSetInfoEx->BufferSize = ValueLength;

   //
   // Create notification event object to be used to signal the
   // request completion.
   //
   ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

   KeInitializeEvent(&SyncEvent, NotificationEvent, FALSE);

   //
   // Build the synchronous request to be sent to the Tcp driver
   //
   ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

   pDeviceObject = IoGetRelatedDeviceObject(
                     pFileObject
                     );

   pIrp = IoBuildDeviceIoControlRequest(
            IOCTL_TCP_SET_INFORMATION_EX,
            pDeviceObject,
            pSetInfoEx,       // Input Buffer
            Length,          // Input Buffer Size
            NULL,       // Output Buffer
            0,          // Output Buffer Size
            FALSE,
            &SyncEvent,
            &IoStatus
            );

   if( pIrp == NULL )
   {
      return STATUS_INSUFFICIENT_RESOURCES;
   }

   pIrpSp = IoGetNextIrpStackLocation( pIrp );
   pIrpSp->FileObject = pFileObject;

   //
   // Pass request to Tcp driver and wait for request to complete.
   //
   Status = IoCallDriver( pDeviceObject, pIrp );

   if( (Status == STATUS_SUCCESS) || (Status == STATUS_PENDING) )
   {
      KeWaitForSingleObject(&SyncEvent, Executive, KernelMode, FALSE, NULL);

      NdisFreeMemory( pSetInfoEx, Length + sizeof( ULONG ), 0 );

      return( IoStatus.Status );
   }

   NdisFreeMemory( pSetInfoEx, Length + sizeof( ULONG ), 0 );

   return( Status );
}

NTSTATUS
KS_TdiCall ( 
   IN PIRP pIrp,
   IN PDEVICE_OBJECT pDeviceObject,
   IN OUT PIO_STATUS_BLOCK pIoStatusBlock
   )
{
   KEVENT kEvent;                                                    // signaling event
   NTSTATUS dStatus = STATUS_INSUFFICIENT_RESOURCES;                 // local status

   KeInitializeEvent ( &kEvent, NotificationEvent, FALSE );          // reset notification event
   pIrp->UserEvent = &kEvent;                                        // pointer to event
   pIrp->UserIosb = pIoStatusBlock;                               // pointer to status block
   dStatus = IoCallDriver ( pDeviceObject, pIrp );                   // call next driver
   if ( dStatus == STATUS_PENDING )                                  // make all request synchronous
   {
      (void)KeWaitForSingleObject ( 
                     (PVOID)&kEvent,                                 // signaling object
                     Executive,                                      // wait reason
                     KernelMode,                                     // wait mode
                     TRUE,                                           // alertable
                     NULL );                                         // timeout
   }
   dStatus = pIoStatusBlock->Status;                           
   return ( dStatus );                                               // return with status
}


NTSTATUS
KS_TCPQueryDeviceControl( 
   IN PFILE_OBJECT pFileObject,
   IN PVOID InputBuffer,
   IN ULONG InputBufferSize,
   IN OUT PVOID OutputBuffer,
   IN ULONG OutputBufferSize,
   OUT PULONG pdReturn
   )
{
   PIRP pIrp;                                   // local i/o request
   PIO_STACK_LOCATION pIoStack;                 // I/O Stack Location
   PDEVICE_OBJECT pDeviceObject;                // local device object
   IO_STATUS_BLOCK IoStatusBlock;               // return status
   NTSTATUS dStatus = STATUS_INVALID_PARAMETER; // default return status

   if ( pFileObject )
   {
      pDeviceObject = IoGetRelatedDeviceObject ( pFileObject );

      pIrp = IoBuildDeviceIoControlRequest(
                  IOCTL_TCP_QUERY_INFORMATION_EX,
                  pDeviceObject,
                  InputBuffer,
                  InputBufferSize,
                  OutputBuffer,
                  OutputBufferSize,
                  FALSE,
                  NULL,    // pointer to event
                  NULL     // pointer to return buffer
                  );

      if ( pIrp == NULL )
      {
         DbgPrint ( "ERROR: IoBuildDeviceIoControlRequest\n" );
         dStatus = STATUS_INSUFFICIENT_RESOURCES;
      }
      else
      {
         pIoStack = IoGetNextIrpStackLocation( pIrp );   // get the iostack
         pIoStack->DeviceObject = pDeviceObject;         // store current device object
         pIoStack->FileObject = pFileObject;             // store file object in the stack

         dStatus = KS_TdiCall( pIrp, pDeviceObject, &IoStatusBlock );

         if ( pdReturn )                                 // requested by user?
            *pdReturn = IoStatusBlock.Information;       // return information size
      }
   }

   return ( dStatus );     // return with status
}


NTSTATUS
KS_TCPQueryInformation(
   PFILE_OBJECT   pFileObject,
   ULONG          Entity,
   ULONG          Instance,
   ULONG          Class,
   ULONG          Type,
   ULONG          Id,
   PVOID          pOutputBuffer,
   PULONG         pdOutputLength
   )
{
   TCP_REQUEST_QUERY_INFORMATION_EX QueryInfo;  // local query information

   RtlZeroMemory( &QueryInfo, sizeof( TCP_REQUEST_QUERY_INFORMATION_EX ) ); // input buffer length

   QueryInfo.ID.toi_entity.tei_entity = Entity;
   QueryInfo.ID.toi_entity.tei_instance = Instance;
   QueryInfo.ID.toi_class = Class;
   QueryInfo.ID.toi_type = Type;
   QueryInfo.ID.toi_id = Id;

   return( KS_TCPQueryDeviceControl(                        // send down device control call
               pFileObject,                                 // current transport/connection object
               &QueryInfo,                                  // input buffer
               sizeof ( TCP_REQUEST_QUERY_INFORMATION_EX ), // input buffer length
               pOutputBuffer,                               // output buffer
               *pdOutputLength,                             // output buffer length
               pdOutputLength                               // return information
               )
            );
}

NTSTATUS
KS_TCPGetIPSNMPInfo(
   PFILE_OBJECT   pFileObject,
   IPSNMPInfo     *pIPSnmpInfo,
   PULONG         pBufferSize
   )
{
   NTSTATUS Status;

   Status = KS_TCPQueryInformation( 
               pFileObject,         // control object
               CL_NL_ENTITY,        // entity
               TL_INSTANCE,         // instance
               INFO_CLASS_PROTOCOL, // class
               INFO_TYPE_PROVIDER,  // type
               IP_MIB_STATS_ID,     // id
               pIPSnmpInfo,         // output buffer
               pBufferSize          // output buffer size
               );

   return( Status );
}


NTSTATUS
KS_TCPGetIPAddrTable(
   PFILE_OBJECT   pFileObject,
   IPAddrEntry    *pIPAddrTable,
   PULONG         pBufferSize
   )
{
   NTSTATUS Status;

   Status = KS_TCPQueryInformation( 
               pFileObject,               // control object
               CL_NL_ENTITY,              // entity
               TL_INSTANCE,               // instance
               INFO_CLASS_PROTOCOL,       // class
               INFO_TYPE_PROVIDER,        // type
               IP_MIB_ADDRTABLE_ENTRY_ID, // id
               pIPAddrTable,              // output buffer
               pBufferSize                // output buffer size
               );

   return( Status );
}


NTSTATUS
KS_TCPGetIPRouteTable(
   PFILE_OBJECT   pFileObject,
   IPRouteEntry   *pIPRouteEntry,
   PULONG         pBufferSize
   )
{
   NTSTATUS Status;

   Status = KS_TCPQueryInformation( 
               pFileObject,               // control object
               CL_NL_ENTITY,              // entity
               TL_INSTANCE,               // instance
               INFO_CLASS_PROTOCOL,       // class
               INFO_TYPE_PROVIDER,        // type
               IP_MIB_RTTABLE_ENTRY_ID,   // id
               pIPRouteEntry,             // output buffer
               pBufferSize                // output buffer size
               );

   return( Status );
}


NTSTATUS
KS_TCPGetIPInterfaceInfoForAddr(
   PFILE_OBJECT      pFileObject,
   IPAddr            theIPAddr,
   PUCHAR            pQueryBuffer,// IPInterfaceInfo size + MAX_PHYSADDR_SIZE for address bytes
   PULONG            pBufferSize
   )
{
   NTSTATUS Status;
   TCP_REQUEST_QUERY_INFORMATION_EX QueryInfo;  // local query information

   RtlZeroMemory( &QueryInfo, sizeof( TCP_REQUEST_QUERY_INFORMATION_EX ) ); // input buffer length

   QueryInfo.ID.toi_entity.tei_entity = CL_NL_ENTITY;
   QueryInfo.ID.toi_entity.tei_instance = TL_INSTANCE;
   QueryInfo.ID.toi_class = INFO_CLASS_PROTOCOL;
   QueryInfo.ID.toi_type = INFO_TYPE_PROVIDER;
   QueryInfo.ID.toi_id = IP_INTFC_INFO_ID;

   RtlCopyMemory(
      &QueryInfo.Context,
      &theIPAddr,
      sizeof( ULONG )
      );

   Status = KS_TCPQueryDeviceControl(                    // send down device control call
               pFileObject,                              // current transport/connection object
               &QueryInfo,                               // input buffer
               sizeof ( TCP_REQUEST_QUERY_INFORMATION_EX ), // input buffer length
               pQueryBuffer,                             // output buffer
               *pBufferSize,                             // output buffer length
               pBufferSize                               // return information
               );

   return( Status );
}



⌨️ 快捷键说明

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