📄 pcatdih.c
字号:
/////////////////////////////////////////////////////////////////////////////
//// INCLUDE FILES
#include "ndis.h"
#include "TDI.H"
#include "TDIKRNL.H"
#include "PCATDIH.h"
#include "inetinc.h"
#include "KSUtil.h"
#include "addr.h"
#include "tcpconn.h"
#include "tcpsend.h"
#include "tcprcv.h"
#include "udpsend.h"
#include "udprcv.h"
// Copyright And Configuration Management ----------------------------------
//
// TDI Filter Driver Entry Module - PCATDIH.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 ---------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
// Forward Procedure Prototypes //
/////////////////////////////////////////////////////////////////////////////
FILE_FULL_EA_INFORMATION UNALIGNED *
FindEA(
PFILE_FULL_EA_INFORMATION StartEA,
CHAR *TargetName,
USHORT TargetNameLength
);
#ifdef DBG
VOID
TDIH_Unload(
PDRIVER_OBJECT DriverObject
);
#endif // DBG
/////////////////////////////////////////////////////////////////////////////
// D E F A U L T F U N C T I O N H A N D L I N G //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//// TDIH_InternalDeviceControlCompletion
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//
NTSTATUS
TDIH_InternalDeviceControlCompletion(
PDEVICE_OBJECT pDeviceObject,
PIRP Irp,
void *Context
)
{
PTDIH_DeviceExtension pTDIH_DeviceExtension;
BOOLEAN CanDetachProceed = FALSE;
PDEVICE_OBJECT pAssociatedDeviceObject = NULL;
pTDIH_DeviceExtension = (PTDIH_DeviceExtension )(Context);
ASSERT( pTDIH_DeviceExtension );
//
// Propogate The IRP Pending Flag
//
if (Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
}
// Ensure that this is a valid device object pointer, else return
// immediately.
pAssociatedDeviceObject = pTDIH_DeviceExtension->pFilterDeviceObject;
if (pAssociatedDeviceObject != pDeviceObject)
{
KdPrint(( "TDIH_InternalDeviceControlCompletion: Invalid Device Object Pointer\n" ));
return(STATUS_SUCCESS);
}
// Note that you could do all sorts of processing at this point
// depending upon the results of the operation. Be careful though
// about what you chose to do, about the fact that this completion
// routine is being invoked in an arbitrary thread context and probably
// at high IRQL.
UTIL_DecrementLargeInteger(
pTDIH_DeviceExtension->OutstandingIoRequests,
(unsigned long)1,
&(pTDIH_DeviceExtension->IoRequestsSpinLock)
);
// If the outstanding count is 0, signal the appropriate event which will
// allow any pending detach to proceed.
UTIL_IsLargeIntegerZero(
CanDetachProceed,
pTDIH_DeviceExtension->OutstandingIoRequests,
&(pTDIH_DeviceExtension->IoRequestsSpinLock)
);
if (CanDetachProceed)
{
// signal the event object. Note that this is simply an
// advisory check we do here (to wake up a sleeping thread).
// It is the responsibility of the thread performing the detach to
// ensure that no operations are truly in progress.
KeSetEvent(&(pTDIH_DeviceExtension->IoInProgressEvent), IO_NO_INCREMENT, FALSE);
}
// Although the success return value is hard-coded here, you can
// return an appropriate value (either success or more-processing-reqd)
// based upon what it is that you wish to do in your completion routine.
return(STATUS_SUCCESS);
}
/////////////////////////////////////////////////////////////////////////////
//// TDIH_DispatchInternalDeviceControl
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//
NTSTATUS
TDIH_DispatchInternalDeviceControl(
PDEVICE_OBJECT pDeviceObject,
PIRP Irp
)
{
NTSTATUS RC = STATUS_SUCCESS;
PIO_STACK_LOCATION IrpSp = NULL;
PTDIH_DeviceExtension pTDIH_DeviceExtension;
PDEVICE_OBJECT pLowerDeviceObject = NULL;
BOOLEAN CompleteIrp = FALSE;
ULONG ReturnedInformation = 0;
// Get a pointer to the device extension that must exist for
// all of the device objects created by the filter driver.
pTDIH_DeviceExtension = (PTDIH_DeviceExtension )(pDeviceObject->DeviceExtension);
// Get the current I/O stack location.
IrpSp = IoGetCurrentIrpStackLocation(Irp);
ASSERT(IrpSp);
//
// Possibly Call Win32 API Device Dispatcher
//
if( pTDIH_DeviceExtension->NodeIdentifier.NodeType == TDIH_NODE_TYPE_W32API_DEVICE )
{
return( W32API_Dispatch( pDeviceObject, Irp ) );
}
#ifdef USE_IP_FILTER
//
// Possibly Call IP Device Filter Dispatcher
//
if( pTDIH_DeviceExtension->NodeIdentifier.NodeType == TDIH_NODE_TYPE_IP_FILTER_DEVICE )
{
return( IPFilter_Dispatch( pDeviceObject, Irp ) );
}
#endif // USE_IP_FILTER
#ifdef USE_AFD_FILTER
//
// Possibly Call AFD Device Filter Dispatcher
//
if( pTDIH_DeviceExtension->NodeIdentifier.NodeType == TDIH_NODE_TYPE_AFD_FILTER_DEVICE )
{
return( AfdFilter_Dispatch( pDeviceObject, Irp ) );
}
#endif // USE_AFD_FILTER
if (((int)IrpSp->FileObject->FsContext2) == TDI_CONNECTION_FILE)
{
switch(IrpSp->MinorFunction)
{
case TDI_SEND:
return( TDIH_TdiSend( pTDIH_DeviceExtension, Irp, IrpSp ) );
case TDI_RECEIVE:
return( TDIH_TdiReceive( pTDIH_DeviceExtension, Irp, IrpSp ) );
case TDI_ASSOCIATE_ADDRESS:
return( TDIH_TdiAssociateAddress( pTDIH_DeviceExtension, Irp, IrpSp ) );
case TDI_DISASSOCIATE_ADDRESS:
return( TDIH_TdiDisAssociateAddress( pTDIH_DeviceExtension, Irp, IrpSp ) );
case TDI_CONNECT:
return( TDIH_TdiConnect( pTDIH_DeviceExtension, Irp, IrpSp ) );
case TDI_DISCONNECT:
return( TDIH_TdiDisconnect( pTDIH_DeviceExtension, Irp, IrpSp ) );
case TDI_LISTEN:
KdPrint(("TdiListen: Entry\n" ));
break;
case TDI_ACCEPT:
KdPrint(("TdiAccept: Entry\n" ));
break;
default:
break;
}
}
else if (((int)IrpSp->FileObject->FsContext2) == TDI_TRANSPORT_ADDRESS_FILE)
{
switch(IrpSp->MinorFunction)
{
case TDI_SEND_DATAGRAM:
return( TDIH_TdiSendDatagram( pTDIH_DeviceExtension, Irp, IrpSp ) );
case TDI_RECEIVE_DATAGRAM:
return( TDIH_TdiReceiveDatagram( pTDIH_DeviceExtension, Irp, IrpSp ) );
case TDI_SET_EVENT_HANDLER:
return( TDIH_TdiSetEvent( pTDIH_DeviceExtension, Irp, IrpSp ) );
default:
break;
}
}
//
// Handle Functions Common To All TDI Objects
//
switch(IrpSp->MinorFunction)
{
case TDI_QUERY_INFORMATION:
{
PTDI_REQUEST_KERNEL_QUERY_INFORMATION p;
p = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&IrpSp->Parameters;
switch( p->QueryType )
{
case TDI_QUERY_BROADCAST_ADDRESS:
KdPrint(("TdiQueryInformation: BROADCAST_ADDRESS\n" ));
break;
case TDI_QUERY_PROVIDER_INFORMATION:
KdPrint(("TdiQueryInformation: PROVIDER_INFORMATION\n" ));
break;
case TDI_QUERY_ADDRESS_INFO:
KdPrint(("TdiQueryInformation: ADDRESS_INFO\n" ));
break;
case TDI_QUERY_CONNECTION_INFO:
KdPrint(("TdiQueryInformation: CONNECTION_INFO\n" ));
break;
case TDI_QUERY_PROVIDER_STATISTICS:
KdPrint(("TdiQueryInformation: PROVIDER_STATISTICS\n" ));
break;
case TDI_QUERY_DATAGRAM_INFO:
KdPrint(("TdiQueryInformation: DATAGRAM_INFO\n" ));
break;
case TDI_QUERY_DATA_LINK_ADDRESS:
KdPrint(("TdiQueryInformation: DATA_LINK_ADDRESS\n" ));
break;
case TDI_QUERY_NETWORK_ADDRESS:
KdPrint(("TdiQueryInformation: NETWORK_ADDRESS\n" ));
break;
case TDI_QUERY_MAX_DATAGRAM_INFO:
KdPrint(("TdiQueryInformation: MAX_DATAGRAM_INFO\n" ));
break;
default:
KdPrint(("TdiQueryInformation: QueryType: %d\n",
p->QueryType ));
break;
}
}
break;
case TDI_SET_INFORMATION:
KdPrint(("TdiSetInformation: Entry\n" ));
break;
case TDI_ACTION:
KdPrint(("TdiAction: Entry\n" ));
break;
default:
break;
}
try
{
pLowerDeviceObject = pTDIH_DeviceExtension->LowerDeviceObject;
// Be careful about not screwing up badly. This is actually not recommended by the I/O Manager.
if (Irp->CurrentLocation == 1)
{
ULONG ReturnedInformation = 0;
// Bad!! Fudge the error code. Break if we can ...
KdPrint(("TDIH_DispatchInternalDeviceControl encountered bogus current location\n"));
KdPrint((" TDIH_DispatchInternalDeviceControl: Node Type: %d, Context2: %d; Major FCN: 0x%2.2X, Minor FCN: 0x%2.2X\n",
pTDIH_DeviceExtension->NodeIdentifier.NodeType,
(int)IrpSp->FileObject->FsContext2,
IrpSp->MajorFunction,
IrpSp->MinorFunction
));
// UTIL_BreakPoint();
RC = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Status = RC;
Irp->IoStatus.Information = ReturnedInformation;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return( RC );
}
//
// Copy Contents Of Current Stack Location To Next Stack Location
//
IoCopyCurrentIrpStackLocationToNext( Irp );
//
// Setup Our Completion Routine
// ============================
// We will specify a default completion routine. This provides us
// with the opportunity to do whatever we like once the function
// processing has been completed.
//
// Specify that our completion routine be invoked regardless of how
// the IRP is completed/cancelled.
//
IoSetCompletionRoutine(
Irp,
TDIH_InternalDeviceControlCompletion,
pTDIH_DeviceExtension,
TRUE,
TRUE,
TRUE
);
// Increment the count of outstanding I/O requests. The count will
// be decremented in the completion routine.
// Acquire a special end-resource spin-lock to synchronize access.
UTIL_IncrementLargeInteger(
pTDIH_DeviceExtension->OutstandingIoRequests,
(unsigned long)1,
&(pTDIH_DeviceExtension->IoRequestsSpinLock)
);
// Clear the fast-IO notification event protected by the resource
// we have acquired.
KeClearEvent(&(pTDIH_DeviceExtension->IoInProgressEvent));
// Forward the request. Note that if the target does not
// wish to service the function, the request will get redirected
// to IopInvalidDeviceRequest() (a routine that completes the
// IRP with STATUS_INVALID_DEVICE_REQUEST).
// However, we must release our resources before forwarding the
// request. That will avoid the sort of problems discussed in
// Chapter 12 of the text.
RC = IoCallDriver(pLowerDeviceObject, Irp);
// Note that at this time, the filter driver completion routine
// does not return STATUS_MORE_PROCESSING_REQUIRED. However, if you
// do modify this code and use it in your own filter driver and if your
// completion routine *could* return the STATUS_MORE_PROCESSING_REQUIRED
// return code, you must not blindly return the return-code obtained from
// the call to IoCallDriver() above. See Chapter 12 for a discussion of
// this issue.
try_return(RC);
try_exit: NOTHING;
}
finally
{
// Complete the IRP only if we must.
if (CompleteIrp)
{
Irp->IoStatus.Status = RC;
Irp->IoStatus.Information = ReturnedInformation;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
}
return(RC);
}
/////////////////////////////////////////////////////////////////////////////
// D E F A U L T F U N C T I O N H A N D L I N G //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//// TDIH_DefaultCompletion
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//
NTSTATUS
TDIH_DefaultCompletion(
PDEVICE_OBJECT pDeviceObject,
PIRP Irp,
void *Context
)
{
PTDIH_DeviceExtension pTDIH_DeviceExtension;
BOOLEAN CanDetachProceed = FALSE;
PDEVICE_OBJECT pAssociatedDeviceObject = NULL;
pTDIH_DeviceExtension = (PTDIH_DeviceExtension )(Context);
ASSERT( pTDIH_DeviceExtension );
//
// Propogate The IRP Pending Flag
//
if (Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
}
// Ensure that this is a valid device object pointer, else return
// immediately.
pAssociatedDeviceObject = pTDIH_DeviceExtension->pFilterDeviceObject;
if (pAssociatedDeviceObject != pDeviceObject)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -