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

📄 ksutil.c

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

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

// Copyright And Configuration Management ----------------------------------
//
//                  TDI Test TCP (TTCP) Utilities - KSUTIL.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
//
// The KS_xxx utilities are general purpose, and are intended to be used
// and incorporated into your own TDI client driver.
//

NDIS_PHYSICAL_ADDRESS HighestAcceptableMax =
    NDIS_PHYSICAL_ADDRESS_CONST(-1,-1);

static NTSTATUS
_I_KS_SimpleTdiRequestComplete(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context
    );

VOID
_I_KS_RefTransportAddress(
   PKS_ADDRESS             pKS_Address
   );

VOID
_I_KS_DerefTransportAddress(
   PKS_ADDRESS             pKS_Address
   );

NTSTATUS
_I_KS_OpenConnectionContext(
   PWSTR          TransportDeviceNameW,// Zero-terminated String
   PKS_ENDPOINT   pKS_Endpoint,
   PVOID          pContext
   );

NTSTATUS
_I_KS_CloseConnectionContext(
   PKS_ENDPOINT   pKS_Endpoint
   );

VOID
_I_KS_RefConnectionEndpoint(
   PKS_ENDPOINT   pKS_Endpoint
   );

VOID
_I_KS_DerefConnectionEndpoint(
   PKS_ENDPOINT   pKS_Endpoint
   );

NTSTATUS
_I_KS_AssociateAddress(
   PKS_ADDRESS    pKS_Address,
   PKS_ENDPOINT pKS_Endpoint
   );

NTSTATUS
_I_KS_DisassociateAddress(
   PKS_ENDPOINT pKS_Endpoint
   );


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

typedef
struct _KS_ADDRESS_REQUEST_CONTEXT
{
   PKS_ADDRESS                      m_pKS_Address;
   HANDLE                           m_CompletionEvent;
   PKS_REQUEST_COMPLETION_ROUTINE   m_CompletionRoutine;
   PVOID                            m_CompletionContext;
   PIO_STATUS_BLOCK                 m_pIoStatusBlock;
   IO_STATUS_BLOCK                  m_SafeIoStatusBlock;
   ULONG                            m_Reserved;
}
   KS_ADDRESS_REQUEST_CONTEXT, *PKS_ADDRESS_REQUEST_CONTEXT;


typedef
struct _KS_ENDPOINT_REQUEST_CONTEXT
{
   PKS_ENDPOINT                     m_pKS_Endpoint;
   HANDLE                           m_CompletionEvent;
   PKS_REQUEST_COMPLETION_ROUTINE   m_CompletionRoutine;
   PVOID                            m_CompletionContext;
   PIO_STATUS_BLOCK                 m_pIoStatusBlock;
   IO_STATUS_BLOCK                  m_SafeIoStatusBlock;
   BOOLEAN                          m_bSynchronous;
   ULONG                            m_Reserved;
}
   KS_ENDPOINT_REQUEST_CONTEXT, *PKS_ENDPOINT_REQUEST_CONTEXT;


/////////////////////////////////////////////////////////////////////////////
//                    A D D R E S S  F U N C T I O N S                     //
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
//// KS_OpenTransportAddress
//
// Purpose
// Open a TDI address object on the specified transport device for the
// specified transport address.
//
// Parameters
//   TransportDeviceNameW
//      Pointer to a zero-terminated wide character string that specifies
//      the transport device. An example would be: L"\\Device\\Tcp"
//
//   pTransportAddress
//      Pointer to a TRANSPORT_ADDRESS structure (typically a TA_IP_ADDRESS
//      structure) that specifies the local address to open.
//
//   pKS_Address
//      Pointer to a caller-provided KS_ADDRESS structure that will be
//      initialized as the transport address object is opened.
//
// Return Value
// Status
//
// Remarks
// See the NT DDK documentation topic "5.1 Opening a Transport Address"
// for more information.
//
// The KS_BuildEaBuffer function is used to build the extended attributes
// buffer.
//
// It is important to note that the call to ZwCreateFile creates a
// client-process-specific file object that represents the transport's
// address object. This means that the m_hAddress handle is only valid
// in the same client process that the ZwCreateFile call was made in.
//
// Fortunately, most TDI operations actually reference the file object
// pointer - not the handle. Operations that do not reference the address
// handle can be performed in arbitrary context unless there are other
// restrictions.
//
// The client process dependency of the address handle does effect
// the design of a TDI Client to some extent. In particular, the
// client process that was used to create an address object must
// continue to exist until the address object is eventually closed.
//
// There are several ways to insure that the client process continues
// to exist while the address object is in use. The most common is to
// create a thread that is attached to the system process. As long as
// the system process continues to exist, the address object handle
// will remain valid.
//
// Callers of KS_OpenTransportAddress must be running at IRQL PASSIVE_LEVEL.
//

NTSTATUS
KS_OpenTransportAddress(
   IN PWSTR                TransportDeviceNameW,// Zero-terminated String
   IN PTRANSPORT_ADDRESS   pTransportAddress,   // Local Transport Address
   PKS_ADDRESS             pKS_Address
   )
{
   NTSTATUS          Status = STATUS_SUCCESS;
   UNICODE_STRING    TransportDeviceName;
   OBJECT_ATTRIBUTES ObjectAttributes;
   IO_STATUS_BLOCK   IoStatusBlock;
   ULONG             TransportAddressLength;
   ULONG             TransportEaBufferLength;
   PFILE_FULL_EA_INFORMATION pTransportAddressEa;
   PDEVICE_OBJECT    pDeviceObject;

   ASSERT( pKS_Address );

   //
   // Initialize KS_ADDRESS Structure
   //
   pKS_Address->m_nStatus = STATUS_UNSUCCESSFUL;
   pKS_Address->m_pFileObject = NULL;
   pKS_Address->m_pAtomicIrp = NULL;
   pKS_Address->m_ReferenceCount = 1;

   InitializeListHead( &pKS_Address->m_ConnectionList );

   TransportAddressLength = KS_TransportAddressLength( pTransportAddress );

   //
   // Setup Transport Device Name
   //
   NdisInitUnicodeString( &TransportDeviceName, TransportDeviceNameW );

   //
   // Build an EA buffer for the specified transport address
   //
   Status = KS_BuildEaBuffer(
               TDI_TRANSPORT_ADDRESS_LENGTH,  // EaName Length
               TdiTransportAddress,           // EaName
               TransportAddressLength,        // EaValue Length
               pTransportAddress,             // EaValue
               &pTransportAddressEa,
               &TransportEaBufferLength
               );

   if( !NT_SUCCESS(Status) )
   {
      return( pKS_Address->m_nStatus = Status );
   }

   ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

   InitializeObjectAttributes(
      &ObjectAttributes,      // OBJECT_ATTRIBUTES instance
      &TransportDeviceName,   // Transport Device Name
      OBJ_CASE_INSENSITIVE,   // Attributes
      NULL,                   // RootDirectory
      NULL                    // SecurityDescriptor
      );

   ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

   //
   // Call Transport To Create Transport Address Object
   //
   Status = ZwCreateFile(
               &pKS_Address->m_hAddress,                   // Handle
               GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, // Desired Access
               &ObjectAttributes,                          // Object Attributes
               &IoStatusBlock,                             // Final I/O status block
               0,                                          // Allocation Size
               FILE_ATTRIBUTE_NORMAL,                      // Normal attributes
               FILE_SHARE_READ,                            // Sharing attributes
               FILE_OPEN_IF,                               // Create disposition
               0,                                          // CreateOptions
               pTransportAddressEa,                        // EA Buffer
               TransportEaBufferLength                     // EA length
               );

   //
   // Free up the EA buffer allocated.
   //
   ExFreePool( (PVOID )pTransportAddressEa );

   if (NT_SUCCESS(Status))
   {
      //
      // Obtain a referenced pointer to the file object.
      //
      ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );

      Status = ObReferenceObjectByHandle(
                  pKS_Address->m_hAddress,   // Object Handle
                  FILE_ANY_ACCESS,           // Desired Access
                  NULL,                      // Object Type
                  KernelMode,                // Processor mode
                  (PVOID *)&pKS_Address->m_pFileObject,   // File Object pointer
                  NULL                       // Object Handle information
                  );

      pDeviceObject = IoGetRelatedDeviceObject( pKS_Address->m_pFileObject );

      //
      // Allocate IRP For General Purpose Use
      //
      pKS_Address->m_pAtomicIrp = IoAllocateIrp(
                                    pDeviceObject->StackSize,
                                    FALSE
                                    );

      if( !pKS_Address->m_pAtomicIrp )
      {
         KS_CloseTransportAddress( pKS_Address );

         return( pKS_Address->m_nStatus = STATUS_INSUFFICIENT_RESOURCES );
      }
   }

   if (NT_SUCCESS(Status))
   {
   }
   else
   {
   }

   return( pKS_Address->m_nStatus = Status );
}


/////////////////////////////////////////////////////////////////////////////
//// _I_KS_RefTransportAddress (INTERNAL/PRIVATE)
//
// Purpose
// This routine increments the reference count on the transport address.
//
// Parameters
//   pKS_Address
//      Pointer to the KS_ADDRESS structure whose reference count should
//      be incremented.
//
// Return Value
// None.
//
// Remarks
//

VOID
_I_KS_RefTransportAddress(
   PKS_ADDRESS pKS_Address
   )
{
   ASSERT( pKS_Address );
   ASSERT( pKS_Address->m_ReferenceCount > 0 );

   if( pKS_Address )
   {
      InterlockedIncrement( &pKS_Address->m_ReferenceCount );
   }
}


/////////////////////////////////////////////////////////////////////////////
//// _I_KS_DestroyTransportAddress (INTERNAL/PRIVATE)
//
// Purpose
// This routine destroys the transport address object.
//
// Parameters
//   pKS_Address
//      Pointer to the KS_ADDRESS structure that specifies the transport
//      address object pointer and handle to be destroyed.
//
// Return Value
// Status
//
// Remarks
// This function will free resources allocated in KS_OpenTransportAddress,
// dereference the transport address file object pointer anc actually
// close the transport address file handle.
//
// Callers of _I_KS_DestroyTransportAddress must be running at IRQL
// PASSIVE_LEVEL.
//

NTSTATUS
_I_KS_DestroyTransportAddress(
   PKS_ADDRESS pKS_Address
   )
{
   NTSTATUS Status = STATUS_SUCCESS;

   KdPrint(("KS_DestroyTransportAddress: Entry...\n"));

   ASSERT( pKS_Address );
   ASSERT( pKS_Address->m_ReferenceCount == 0 );
   ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
   ASSERT( IsListEmpty( &pKS_Address->m_ConnectionList ) );

   if( !pKS_Address )
   {
      return( STATUS_SUCCESS );
   }

   //
   // Free IRP Allocated For Receiveing
   //
   if( pKS_Address->m_pAtomicIrp )
   {
      IoFreeIrp( pKS_Address->m_pAtomicIrp );
   }

   pKS_Address->m_pAtomicIrp = NULL;


   //
   // Free IRP Allocated For Sending
   //
   //
   // Dereference The File Object
   //
   if( pKS_Address->m_pFileObject != NULL )
   {
      ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
      ObDereferenceObject( pKS_Address->m_pFileObject );
   }

   pKS_Address->m_pFileObject = NULL;

   ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
   ZwClose( pKS_Address->m_hAddress );

   return Status;
}


/////////////////////////////////////////////////////////////////////////////
//// _I_KS_DerefTransportAddress (INTERNAL/PRIVATE)
//
// Purpose
// This routine decrements the reference count on the transport address.
//
// Parameters
//   pKS_Address
//      Pointer to the KS_ADDRESS structure whose reference count should be
//      decremented.
//
// Return Value
// None.
//
// Remarks
// The KS_ADDRESS structure will continue to exist until the reference count
// is deceremented to zero. When ther reference count is decremented to zero

⌨️ 快捷键说明

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