📄 pcatdih.c
字号:
// 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 )(DeviceObject->DeviceExtension);
// Get the current I/O stack location.
IrpSp = IoGetCurrentIrpStackLocation(Irp);
ASSERT(IrpSp);
ASSERT(IrpSp->MajorFunction != IRP_MJ_INTERNAL_DEVICE_CONTROL);
//
// Possibly Call Win32 API Device Dispatcher
//
if( pTDIH_DeviceExtension->NodeIdentifier.NodeType == TDIH_NODE_TYPE_W32API_DEVICE )
{
return( W32API_Dispatch( DeviceObject, 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( DeviceObject, 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( DeviceObject, Irp ) );
}
#endif // USE_AFD_FILTER
switch(IrpSp->MajorFunction)
{
case IRP_MJ_CREATE:
return( TDIH_Create(pTDIH_DeviceExtension, Irp, IrpSp) );
case IRP_MJ_CLEANUP:
return( TDIH_Cleanup(pTDIH_DeviceExtension, Irp, IrpSp) );
case IRP_MJ_DEVICE_CONTROL:
RC = TdiMapUserRequest(DeviceObject, Irp, IrpSp);
if( RC == STATUS_SUCCESS )
{
KdPrint(("TDIH_DefaultDispatch: Mapped DeviceControl To InternalDeviceControl\n" ));
return( TDIH_DispatchInternalDeviceControl(DeviceObject, Irp));
}
return( TDIH_DispatchDeviceControl( DeviceObject, Irp, IrpSp ) );
case IRP_MJ_CLOSE:
return( TDIH_Close(pTDIH_DeviceExtension, Irp, IrpSp) );
case IRP_MJ_QUERY_SECURITY:
KdPrint(("TDIH_DefaultDispatch: IRP_MJ_QUERY_SECURITY\n" ));
break;
case IRP_MJ_WRITE:
KdPrint(("TDIH_DefaultDispatch: IRP_MJ_WRITE\n" ));
break;
case IRP_MJ_READ:
KdPrint(("TDIH_DefaultDispatch: IRP_MJ_READ\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(("PCATDIH: TDIH_DefaultDispatch encountered bogus current location\n"));
// UTIL_BreakPoint();
RC = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Status = RC;
Irp->IoStatus.Information = ReturnedInformation;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return( RC );
}
switch( pTDIH_DeviceExtension->NodeIdentifier.NodeType )
{
case TDIH_NODE_TYPE_TCP_FILTER_DEVICE:
KdPrint(("TDIH_DefaultDispatch: TCP, Major FCN: 0x%2.2X, Minor FCN: 0x%2.2X\n",
IrpSp->MajorFunction,
IrpSp->MinorFunction
));
break;
case TDIH_NODE_TYPE_UDP_FILTER_DEVICE:
KdPrint(("TDIH_DefaultDispatch: UDP, Major FCN: 0x%2.2X, Minor FCN: 0x%2.2X\n",
IrpSp->MajorFunction,
IrpSp->MinorFunction
));
break;
case TDIH_NODE_TYPE_RAW_IP_FILTER_DEVICE:
KdPrint(("TDIH_DefaultDispatch: RAW IP, Major FCN: 0x%2.2X, Minor FCN: 0x%2.2X\n",
IrpSp->MajorFunction,
IrpSp->MinorFunction
));
break;
case TDIH_NODE_TYPE_IP_FILTER_DEVICE:
default:
KdPrint(("TDIH_DefaultDispatch: Target Object: 0x%x, Major FCN: 0x%2.2X, Minor FCN: 0x%2.2X\n",
pLowerDeviceObject,
IrpSp->MajorFunction,
IrpSp->MinorFunction
));
break;
}
//
// 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_DefaultCompletion,
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
{
}
return(RC);
}
/////////////////////////////////////////////////////////////////////////////
// D R I V E R E N T R Y //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//// DriverEntry
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//
NTSTATUS
DriverEntry(
PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath
)
{
NTSTATUS status;
ULONG i;
KdPrint(("PCATDIH: Driver Entry...\n"));
//
// Initialize Global Variables
//
InitializeListHead( &FreeAddrObjList );
InitializeListHead( &OpenAddrObjList );
InitializeListHead( &AddrObjExInfoList );
InitializeListHead( &FreeTCPConnList );
InitializeListHead( &OpenTCPConnList );
//
// Initialize Process Name Finding Machanism
//
KS_InitProcessNameOffset();
//
// Initialize Our Driver Object
//
#ifdef DBG
DriverObject->DriverUnload = TDIH_Unload;
#else
DriverObject->DriverUnload = NULL;
#endif
//
// Setup MajorFunction Table
// -------------------------
// See additional comments for TDIH_DefaultDispatch.
//
for (i=0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
{
DriverObject->MajorFunction[i] = TDIH_DefaultDispatch;
}
//
// Special Case Internal Device Controls
//
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] =
TDIH_DispatchInternalDeviceControl;
#ifdef USE_IP_FILTER
//
// Attach Our Filter Over IP Device
//
status = IPFilter_Attach( DriverObject, RegistryPath );
#endif // USE_IP_FILTER
//
// Attach Our Filter Over TCP Device
//
status = TCPFilter_Attach( DriverObject, RegistryPath );
//
// Attach Our Filter Over UDP Device
//
status = UDPFilter_Attach( DriverObject, RegistryPath );
#ifdef USE_RAW_IP_FILTER
//
// Attach Our Filter Over RAW IP Device
//
status = RawIPFilter_Attach( DriverObject, RegistryPath );
#endif // USE_RAW_IP_FILTER
#ifdef USE_AFD_FILTER
//
// Attach Our Filter Over AFD Device
//
status = AfdFilter_Attach( DriverObject, RegistryPath );
#endif // USE_AFD_FILTER
//
// Initialize Our Win32 API Device
//
status = W32API_Initialize( DriverObject, RegistryPath );
return status;
}
/////////////////////////////////////////////////////////////////////////////
//// FindEA
//
// Purpose
// Parses an extended attribute list for a given target attribute.
//
// Parameters
//
// Return Value
//
// Remarks
//
FILE_FULL_EA_INFORMATION UNALIGNED * // Returns: requested attribute or NULL.
FindEA(
PFILE_FULL_EA_INFORMATION StartEA, // First extended attribute in list.
CHAR *TargetName, // Name of target attribute.
USHORT TargetNameLength) // Length of above.
{
USHORT i;
BOOLEAN found;
FILE_FULL_EA_INFORMATION UNALIGNED *CurrentEA;
PAGED_CODE();
if( !StartEA )
{
return( NULL );
}
do
{
found = TRUE;
CurrentEA = StartEA;
StartEA += CurrentEA->NextEntryOffset;
if (CurrentEA->EaNameLength != TargetNameLength)
{
continue;
}
for (i=0; i < CurrentEA->EaNameLength; i++)
{
if (CurrentEA->EaName[i] == TargetName[i])
{
continue;
}
found = FALSE;
break;
}
if (found)
{
return(CurrentEA);
}
}
while(CurrentEA->NextEntryOffset != 0);
return(NULL);
}
#ifdef DBG
/////////////////////////////////////////////////////////////////////////////
//// TDIH_Unload
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//
VOID
TDIH_Unload(
PDRIVER_OBJECT DriverObject
)
{
PDEVICE_OBJECT pDeviceObject;
PDEVICE_OBJECT pNextDeviceObject;
PTDIH_DeviceExtension pTDIH_DeviceExtension;
KdPrint(("TDIH_Unload: Entry...\n"));
pDeviceObject = DriverObject->DeviceObject;
while( pDeviceObject != NULL )
{
pNextDeviceObject = pDeviceObject->NextDevice;
pTDIH_DeviceExtension = (PTDIH_DeviceExtension )pDeviceObject->DeviceExtension;
//
// Detach Based On Filter Type
//
if( pTDIH_DeviceExtension->NodeIdentifier.NodeType == TDIH_NODE_TYPE_TCP_FILTER_DEVICE )
{
TCPFilter_Detach( pDeviceObject ); // Calls IoDeleteDevice
}
else if( pTDIH_DeviceExtension->NodeIdentifier.NodeType == TDIH_NODE_TYPE_UDP_FILTER_DEVICE )
{
UDPFilter_Detach( pDeviceObject ); // Calls IoDeleteDevice
}
#ifdef USE_IP_FILTER
else if( pTDIH_DeviceExtension->NodeIdentifier.NodeType == TDIH_NODE_TYPE_IP_FILTER_DEVICE )
{
IPFilter_Detach( pDeviceObject ); // Calls IoDeleteDevice
}
#endif // USE_IP_FILTER
#ifdef USE_RAW_IP_FILTER
else if( pTDIH_DeviceExtension->NodeIdentifier.NodeType == TDIH_NODE_TYPE_RAW_IP_FILTER_DEVICE )
{
RawIPFilter_Detach( pDeviceObject ); // Calls IoDeleteDevice
}
#endif // USE_RAW_IP_FILTER
#ifdef USE_AFD_FILTER
else if( pTDIH_DeviceExtension->NodeIdentifier.NodeType == TDIH_NODE_TYPE_AFD_FILTER_DEVICE )
{
AfdFilter_Detach( pDeviceObject ); // Calls IoDeleteDevice
}
#endif // USE_AFD_FILTER
else if( pTDIH_DeviceExtension->NodeIdentifier.NodeType == TDIH_NODE_TYPE_W32API_DEVICE )
{
W32API_Unload( pDeviceObject ); // Calls IoDeleteDevice
}
else
{
KdPrint(("PCATDIH: Unknown Node Type!!!\n"));
}
pDeviceObject = pNextDeviceObject;
}
if( !IsListEmpty( &FreeAddrObjList ) )
{
KdPrint(( " FreeAddrObjList Not Empty!!!\n" ));
}
if( !IsListEmpty( &OpenAddrObjList ) )
{
KdPrint(( " OpenAddrObjList Not Empty!!!\n" ));
}
if( !IsListEmpty( &FreeTCPConnList ) )
{
KdPrint(( " FreeTCPConnList Not Empty!!!\n" ));
}
if( !IsListEmpty( &OpenTCPConnList ) )
{
KdPrint(( " OpenTCPConnList Not Empty!!!\n" ));
}
KdPrint(("TDIH_Unload: Exit!!!\n"));
}
#endif // DBG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -