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

📄 w32api.c

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

#include "ndis.h"
#include "TDI.H"
#include "TDIKRNL.H"
#include "PCATDIH.h"
#include "TDIHApi.h" // In ..\..\Include directory
#include "KSUtil.h"
#include "addr.h"

// Copyright And Configuration Management ----------------------------------
//
//               TDI Filter Driver Win32 API Dispatch - W32Api.c
//
//                Transport Data Interface (TDI) Filter Samples
//                                    For
//                                 Windows NT
//
//       Copyright (c) 2000, Printing Communications Associates, Inc.
//
//                             Thomas F. Divine
//                           4201 Brunswick Court
//                        Smyrna, Georgia 30080 USA
//                              (770) 432-4580
//                            tdivine@pcausa.com
// 
// End ---------------------------------------------------------------------


/////////////////////////////////////////////////////////////////////////////
//                      W I N 3 2  A P I  D E V I C E                      //
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
//// W32API_InitDeviceExtension
//
// Purpose
//
// Parameters
//
// Return Value
// 
// Remarks
//

NTSTATUS
W32API_InitDeviceExtension(
   PTDIH_DeviceExtension pTDIH_DeviceExtension
   )
{
   NdisZeroMemory( pTDIH_DeviceExtension, sizeof( TDIH_DeviceExtension ) );

   pTDIH_DeviceExtension->NodeIdentifier.NodeType = TDIH_NODE_TYPE_W32API_DEVICE;
   pTDIH_DeviceExtension->NodeIdentifier.NodeSize = sizeof( TDIH_DeviceExtension );

   return( STATUS_SUCCESS );
}


/////////////////////////////////////////////////////////////////////////////
//// W32API_Initialize
//
// Purpose
// Initialize the "Win32 API" device.
//
// Parameters
//
// Return Value
// 
// Remarks
//

NTSTATUS
W32API_Initialize(
   IN PDRIVER_OBJECT DriverObject,
   IN PUNICODE_STRING RegistryPath
   )
{
   NTSTATUS                status;
   UNICODE_STRING          uniNtNameString;
   UNICODE_STRING          uniWin32NameString;
   PTDIH_DeviceExtension   pTDIH_DeviceExtension;
   PDEVICE_OBJECT          pFilterDeviceObject = NULL;
   PDEVICE_OBJECT          pTargetDeviceObject = NULL;
   PFILE_OBJECT            pTargetFileObject = NULL;
   PDEVICE_OBJECT          pLowerDeviceObject = NULL;

   KdPrint(("PCATDIH: W32API_Initialize Entry...\n"));

   //
   // Create counted string version of our Win32 API device name.
   //
   ASSERT( KeGetCurrentIrql() <= DISPATCH_LEVEL );
   RtlInitUnicodeString( &uniNtNameString, TDIH_W32API_DEVICE_NAME );

   //
   // Create The Win32 API Device Object
   // ----------------------------------
   // IoCreateDevice zeroes the memory occupied by the object.
   //
   ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
   status = IoCreateDevice(
               DriverObject,
               sizeof( TDIH_DeviceExtension ),
               &uniNtNameString,
               FILE_DEVICE_UNKNOWN,
               0,                     // No standard device characteristics
               FALSE,                 // This isn't an exclusive device
               &pFilterDeviceObject
               );

   if( !NT_SUCCESS(status) )
   {
      KdPrint(("PCATDIH: Couldn't create the W32API Device Object\n"));

      return( status );
   }

   //
   // Initialize The Extension For The Win32 API Device Object
   //
   pTDIH_DeviceExtension = (PTDIH_DeviceExtension )( pFilterDeviceObject->DeviceExtension );

   W32API_InitDeviceExtension( pTDIH_DeviceExtension );

   //
   // Create counted string version of our Win32 device name.
   //
   RtlInitUnicodeString( &uniWin32NameString, TDIH_W32API_DOS_DEVICE_NAME );

   //
   // Create a link from our device name to a name in the Win32 namespace.
   //
   status = IoCreateSymbolicLink( &uniWin32NameString, &uniNtNameString );

   if (!NT_SUCCESS(status))
   {
      KdPrint( ("PCATDIH: Couldn't create the PCATDIH symbolic link\n") );

      IoDeleteDevice( DriverObject->DeviceObject );
   }
   else
   {
      KdPrint( ("PCATDIH: Win32 API Device Initialized!\n") );
   }

   return status;
}


/////////////////////////////////////////////////////////////////////////////
//// W32API_TestOpenAddress
//
// Purpose
// Test W32API DeviceIoControl mechanism and test handling of calls
// to TDI that are initiated from within the TDI Filter driver itself.
//
// Parameters
//
// Return Value
// 
// Remarks
// This function can be invoked by running the TDIHTest.EXE Win32 console
// application.
//

NTSTATUS
W32API_TestOpenAddress()
{
   NTSTATUS          Status = STATUS_SUCCESS;
   KS_ADDRESS        m_KS_Address;
   TA_IP_ADDRESS     m_LocalAddress;   // TDI Address
   AddrObjExInfo  m_AddrObjExInfo;

   //
   // Setup Local TDI Address
   //
   KS_InitIPAddress(
      &m_LocalAddress,
      INADDR_ANY,    // Any Local Address
      0              // Any Local Port
      );

   //
   // Special Handling For Address Objects Created In The TDI Filter
   // --------------------------------------------------------------
   // Understand that if you initiate TDI calls from within a filter
   // driver, your calls will be handled by your filter. In many cases
   // this may lead to undesirable results. Instead, you may want to
   // filter (or more specifically, NOT filter) your own TDI operations.
   //
   // The following mechanism provides a means to specially identify your
   // own call to KS_OpenTransportAddress when it is subsequently handled
   // in the TDIH_TdiOpenAddressComplete function (which see, in Addr.c).
   //
   // The AddrObjExInfo structure, build below and placed in a list, can
   // be recognized in the TDIH_TdiOpenAddressComplete function. In that
   // function information in the aox_data1 and aox_data2 fields is saved
   // in the AddrObj when it is created. In addition, the aox_valid field
   // is set to TRUE.
   //
   // Understand that most TDI operations of interest directly or indirectly
   // reference an AddrObj. For example, a TCPConn structure has a pointer
   // to the AddrObj that it is associated with. So, simply identifying
   // the AddrObj as "special (e.g., aox_valid == TRUE) is enough to
   // allow all filter functions to know that the address object and it
   // associated connection objects must be handled some special way.
   // The additional aox_data1 and aox_data2 fields (or more of your own
   // invention) can be used to control special processing that you may
   // need to do.
   //
   // In addition, the aox_ao field in your AddrObjExInfo will be filled
   // in with a pointer to the AddrObj structure that was created by
   // TDIH_TdiOpenAddressComplete.
   //
   // The PassThru sample driver doesn't actually use this information.
   // However, it was felt that providing a mechanism to accomodate this
   // situation would be beneficial.
   //
   m_AddrObjExInfo.aox_thread = PsGetCurrentThread();
   m_AddrObjExInfo.aox_data1 = 0x12345678L;
   m_AddrObjExInfo.aox_data2 = NULL;

   InsertTailList(
      &AddrObjExInfoList,
      &m_AddrObjExInfo.aox_q
      );

   //
   // Open Transport Address
   //
   Status = KS_OpenTransportAddress(
                  TCP_DEVICE_NAME_W,
                  (PTRANSPORT_ADDRESS )&m_LocalAddress,
                  &m_KS_Address
                  );

   //
   // Remove The AddrObjExInfo Structure
   //
   RemoveEntryList( &m_AddrObjExInfo.aox_q );

   if( !NT_SUCCESS( Status ) )
   {
      //
      // Address Object Could Not Be Created
      //
      KdPrint(("PCATDIH: W32API_TestOpenAddress could not open address\n"));

      return( Status );
   }

   KdPrint(("PCATDIH: W32API_TestOpenAddress opened address\n"));

   KS_CloseTransportAddress( &m_KS_Address );

   return( Status );
}


/////////////////////////////////////////////////////////////////////////////
//// W32API_Dispatch
//
// Purpose
// The "Win32 API Device" function dispatcher.
//
// Parameters
//
// Return Value
// 
// Remarks
// The "Win32 API Device" is a skeleton of a "traditional" NT device
// handler. It is intended that it be used to support an interface to
// Win32 applications or other NT devices. It is the device that could
// be opened using CreateFile from a Win32 application. The code would
// look something like this:
// 
//   hTest = CreateFile(
//             "\\\\.\\PCATDIH",
//             GENERIC_READ | GENERIC_WRITE,
//             0,
//             NULL,
//             OPEN_EXISTING,
//             FILE_ATTRIBUTE_NORMAL,
//             NULL
//             );
//
// This function is called from the TDIH_DefaultDispatch first-level
// dispatcher in PCATDIH.c.
//

NTSTATUS
W32API_Dispatch(
   IN PDEVICE_OBJECT DeviceObject,
   IN PIRP Irp
   )
{
   PIO_STACK_LOCATION  irpStack;
   PVOID               ioBuffer;
   ULONG               inputBufferLength;
   ULONG               outputBufferLength;
   ULONG               ioControlCode;
   NTSTATUS            Status = STATUS_SUCCESS;

   //
   // Init to default settings- 
   //
   Irp->IoStatus.Status      = STATUS_SUCCESS;
   Irp->IoStatus.Information = 0;

   //
   // Get a pointer to the current location in the Irp. This is where
   //     the function codes and parameters are located.
   //
   irpStack = IoGetCurrentIrpStackLocation(Irp);

   //
   // Get the pointer to the input/output buffer and it's length
   //
   ioBuffer           = Irp->AssociatedIrp.SystemBuffer;
   inputBufferLength  = irpStack->Parameters.DeviceIoControl.InputBufferLength;
   outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;

   switch (irpStack->MajorFunction)
   {
      case IRP_MJ_CREATE:
         KdPrint(("PCATDIH: W32API_Dispatch Create\n"));
         break;

      case IRP_MJ_CLOSE:
         KdPrint(("PCATDIH: W32API_Dispatch Close\n"));
         break;

      case IRP_MJ_CLEANUP:
         KdPrint(("PCATDIH: W32API_Dispatch Cleanup\n"));
         break;

      case IRP_MJ_SHUTDOWN:
         KdPrint(("PCATDIH: W32API_Dispatch Shutdown\n"));
         break;

      case IRP_MJ_DEVICE_CONTROL:
         //
         // get control code from stack and perform the operation
         //
         ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
         switch (ioControlCode)
         {
            // This is where you would add your IOCTL handlers          
            case IOCTL_W32API_TEST:
               KdPrint(("PCATDIH: W32API_Dispatch TEST IOCTL\n"));
               Status = W32API_TestOpenAddress();
               break;

            default:
               KdPrint(("PCATDIH: W32API_Dispatch IOCTL: 0x%8.8X\n",
                  ioControlCode ));
               Status = STATUS_INVALID_PARAMETER;
               break;

         }
         break;

      default:
         KdPrint(("PCATDIH: W32API_Dispatch MJ FCN: 0x%8.8X\n",
            irpStack->MajorFunction ));
         Status = STATUS_UNSUCCESSFUL;
         break;
   }

   //
   // all requests complete synchronously; notify caller of status
   //
   Irp->IoStatus.Status = Status;
   Irp->IoStatus.Information = outputBufferLength;

   IoCompleteRequest(Irp, IO_NO_INCREMENT);

   return Status;
}


#ifdef DBG

/////////////////////////////////////////////////////////////////////////////
//// W32API_Unload
//
// Purpose
//
// Parameters
//
// Return Value
// 
// Remarks
//

VOID
W32API_Unload(
   PDEVICE_OBJECT pDeviceObject
   )
{
   PTDIH_DeviceExtension pTDIH_DeviceExtension;
   BOOLEAN		NoRequestsOutstanding = FALSE;
   UNICODE_STRING uniWin32NameString;

   KdPrint( ("PCATDIH: W32API_Unload Entry...\n") );

   pTDIH_DeviceExtension = (PTDIH_DeviceExtension )pDeviceObject->DeviceExtension;

   ASSERT( pTDIH_DeviceExtension );

   try
   {
      //
      // Create counted string version of our Win32 API device name.
      //
      ASSERT( KeGetCurrentIrql() <= DISPATCH_LEVEL );
      RtlInitUnicodeString( &uniWin32NameString, TDIH_W32API_DOS_DEVICE_NAME );

      //
      // Delete the link from our device name to a name in the Win32 namespace.
      //
      IoDeleteSymbolicLink( &uniWin32NameString );

		// Delete our device object. But first, take care of the device extension.
	   pTDIH_DeviceExtension->NodeIdentifier.NodeType = 0;
	   pTDIH_DeviceExtension->NodeIdentifier.NodeSize = 0;

		// Note that on 4.0 and later systems, this will result in a recursive fast detach.
		IoDeleteDevice( pDeviceObject );

      KdPrint(("PCATDIH: W32API_Unload Finished\n"));
	}
   except (EXCEPTION_EXECUTE_HANDLER)
   {
		// Eat it up.
		;
	}

	return;
}

#endif // DBG



⌨️ 快捷键说明

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