2013年9月10日星期二

过滤命名管道和邮件槽的操作

#include <ntifs.h>

/*
一下是微软官方的回信:
Hi Kou,
Thanks for your feedback question about this topic.
In the Windows kernel, mailslot and named pipe operations are handled as file I/O.
Prior to Windows 8, the filter manager did not direct I/O for these ‘file types’ to the registered minifilters.
You would need to create a legacy style filter to capture any I/O for a mailslot or a named pipe.
Starting with Windows 8, however, your minifilter can register to filter I/O for the mailslot and named pipe file types also.
Thanks again,
Galen

本文的功能是附加并过滤下面两个对象的操作.
L"\\Device\\NamedPipe"
L"\\Device\\Mailslot"
没有fastio会蓝屏的,这个费了我一周的时间才解决,刚开始是确信没有fastio的,这是错误的.

named pipe测试代码:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365588(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365592(v=vs.85).aspx

Mailslots测试代码:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365160(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365802(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365785(v=vs.85).aspx

made by correy
made at 2013.09.05
email:kouleguan at hotmail dot com
homepage:http://correy.webs.com
*/

#define TAG 'tset' //test

typedef struct _FILTER_DEVICE_EXTENSION{
    int type; //可以填写的值有NPFS,MSFS,CD0
    PDEVICE_OBJECT NextDeviceObject;
} FILTER_DEVICE_EXTENSION, * PFILTER_DEVICE_EXTENSION;

PDRIVER_OBJECT g_p_DriverObject;

#define VALID_FAST_IO_DISPATCH_HANDLER(_FastIoDispatchPtr, _FieldName) \
  (((_FastIoDispatchPtr) != NULL) && (((_FastIoDispatchPtr)->SizeOfFastIoDispatch) >= (FIELD_OFFSET(FAST_IO_DISPATCH, _FieldName) + sizeof(void *))) && ((_FastIoDispatchPtr)->_FieldName != NULL))
 
BOOLEAN FsFilterFastIoCheckIfPossible(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in ULONG Length,__in BOOLEAN Wait,__in ULONG LockKey,__in BOOLEAN CheckForReadOperation,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoCheckIfPossible)) return (fastIoDispatch->FastIoCheckIfPossible)(FileObject, FileOffset, Length, Wait, LockKey, CheckForReadOperation, IoStatus, nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoRead(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in ULONG Length,__in BOOLEAN Wait,__in ULONG LockKey,__out PVOID Buffer,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoRead)) return (fastIoDispatch->FastIoRead)( FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoWrite(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in ULONG Length,__in BOOLEAN Wait,__in ULONG LockKey,__in PVOID Buffer,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoWrite)) return (fastIoDispatch->FastIoWrite)( FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoQueryBasicInfo(__in PFILE_OBJECT FileObject,__in BOOLEAN Wait,__out PFILE_BASIC_INFORMATION Buffer,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoQueryBasicInfo)) return (fastIoDispatch->FastIoQueryBasicInfo)( FileObject, Wait, Buffer, IoStatus, nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoQueryStandardInfo(__in PFILE_OBJECT FileObject,__in BOOLEAN Wait,__out PFILE_STANDARD_INFORMATION Buffer,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoQueryStandardInfo)) return (fastIoDispatch->FastIoQueryStandardInfo)(FileObject,Wait,Buffer,IoStatus,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoLock(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in PLARGE_INTEGER Length,__in PEPROCESS ProcessId,__in ULONG Key,__in BOOLEAN FailImmediately,__in BOOLEAN ExclusiveLock,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoLock)) return (fastIoDispatch->FastIoLock)(FileObject,FileOffset,Length,ProcessId,Key,FailImmediately,ExclusiveLock,IoStatus,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoUnlockSingle(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in PLARGE_INTEGER Length,__in PEPROCESS ProcessId,__in ULONG Key,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoUnlockSingle)) return (fastIoDispatch->FastIoUnlockSingle)(FileObject,FileOffset,Length,ProcessId,Key,IoStatus,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoUnlockAll(__in PFILE_OBJECT FileObject,__in PEPROCESS ProcessId,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoUnlockAll)) return (fastIoDispatch->FastIoUnlockAll)(FileObject,ProcessId,IoStatus,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoUnlockAllByKey(__in PFILE_OBJECT FileObject,__in PVOID ProcessId,__in ULONG Key,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoUnlockAllByKey)) return (fastIoDispatch->FastIoUnlockAllByKey)(FileObject,ProcessId,Key,IoStatus,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoDeviceControl(__in PFILE_OBJECT FileObject,__in BOOLEAN Wait,__in_opt PVOID InputBuffer,__in ULONG InputBufferLength,__out_opt PVOID OutputBuffer,__in ULONG OutputBufferLength,__in ULONG IoControlCode,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoDeviceControl)) return (fastIoDispatch->FastIoDeviceControl)(FileObject,Wait,InputBuffer,InputBufferLength,OutputBuffer,OutputBufferLength,IoControlCode,IoStatus,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoQueryNetworkOpenInfo(__in PFILE_OBJECT FileObject,__in BOOLEAN Wait,__out PFILE_NETWORK_OPEN_INFORMATION Buffer,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoQueryNetworkOpenInfo)) return (fastIoDispatch->FastIoQueryNetworkOpenInfo)(FileObject,Wait,Buffer,IoStatus,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoMdlRead(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in ULONG Length,__in ULONG LockKey,__out PMDL* MdlChain,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, MdlRead)) return (fastIoDispatch->MdlRead)(FileObject,FileOffset,Length,LockKey,MdlChain,IoStatus,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoMdlReadComplete(__in PFILE_OBJECT FileObject,__in PMDL MdlChain,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, MdlReadComplete)) return (fastIoDispatch->MdlReadComplete)(FileObject,MdlChain,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoPrepareMdlWrite(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in ULONG Length,__in ULONG LockKey,__out PMDL* MdlChain,__out PIO_STATUS_BLOCK IoStatus,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, PrepareMdlWrite)) return (fastIoDispatch->PrepareMdlWrite)(FileObject,FileOffset,Length,LockKey,MdlChain,IoStatus,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoMdlWriteComplete(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in PMDL MdlChain,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, MdlWriteComplete)) return (fastIoDispatch->MdlWriteComplete)(FileObject,FileOffset,MdlChain,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoReadCompressed(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in ULONG Length,__in ULONG LockKey,__out PVOID Buffer,__out PMDL* MdlChain,__out PIO_STATUS_BLOCK IoStatus,__out struct _COMPRESSED_DATA_INFO* CompressedDataInfo,__in ULONG CompressedDataInfoLength,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoReadCompressed)) return (fastIoDispatch->FastIoReadCompressed)(FileObject,FileOffset,Length,LockKey,Buffer,MdlChain,IoStatus,CompressedDataInfo,CompressedDataInfoLength,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoWriteCompressed(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in ULONG Length,__in ULONG LockKey,__in PVOID Buffer,__out PMDL* MdlChain,__out PIO_STATUS_BLOCK IoStatus,__in struct _COMPRESSED_DATA_INFO* CompressedDataInfo,__in ULONG CompressedDataInfoLength,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoWriteCompressed)) return (fastIoDispatch->FastIoWriteCompressed)(FileObject,FileOffset,Length,LockKey,Buffer,MdlChain,IoStatus,CompressedDataInfo,CompressedDataInfoLength,nextDeviceObject );
  return FALSE;
}

BOOLEAN FsFilterFastIoMdlReadCompleteCompressed(__in PFILE_OBJECT FileObject,__in PMDL MdlChain,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, MdlReadCompleteCompressed)) return (fastIoDispatch->MdlReadCompleteCompressed)(FileObject,MdlChain,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoMdlWriteCompleteCompressed(__in PFILE_OBJECT FileObject,__in PLARGE_INTEGER FileOffset,__in PMDL MdlChain,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, MdlWriteCompleteCompressed)) return (fastIoDispatch->MdlWriteCompleteCompressed)(FileObject,FileOffset,MdlChain,nextDeviceObject);
  return FALSE;
}

BOOLEAN FsFilterFastIoQueryOpen(__in PIRP Irp,__out PFILE_NETWORK_OPEN_INFORMATION NetworkInformation,__in PDEVICE_OBJECT DeviceObject)
{
  PDEVICE_OBJECT  nextDeviceObject = ((PFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextDeviceObject;
  PFAST_IO_DISPATCH fastIoDispatch  = nextDeviceObject->DriverObject->FastIoDispatch;
  if (VALID_FAST_IO_DISPATCH_HANDLER(fastIoDispatch, FastIoQueryOpen))
  {
    BOOLEAN result;
    PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
    irpSp->DeviceObject = nextDeviceObject;
    result = (fastIoDispatch->FastIoQueryOpen)(Irp,NetworkInformation,nextDeviceObject);
    irpSp->DeviceObject = DeviceObject;
    return result;
  }
  return FALSE;
}

VOID FsFilterFastIoDetachDevice(__in PDEVICE_OBJECT SourceDevice,__in PDEVICE_OBJECT TargetDevice)
{
  IoDetachDevice(TargetDevice);
  IoDeleteDevice(SourceDevice);
}

FAST_IO_DISPATCH g_fastIoDispatch ={
  sizeof(FAST_IO_DISPATCH),
  FsFilterFastIoCheckIfPossible,
  FsFilterFastIoRead,
  FsFilterFastIoWrite,
  FsFilterFastIoQueryBasicInfo,
  FsFilterFastIoQueryStandardInfo,
  FsFilterFastIoLock,
  FsFilterFastIoUnlockSingle,
  FsFilterFastIoUnlockAll,
  FsFilterFastIoUnlockAllByKey,
  FsFilterFastIoDeviceControl,
  NULL,
  NULL,
  FsFilterFastIoDetachDevice,
  FsFilterFastIoQueryNetworkOpenInfo,
  NULL,
  FsFilterFastIoMdlRead,
  FsFilterFastIoMdlReadComplete,
  FsFilterFastIoPrepareMdlWrite,
  FsFilterFastIoMdlWriteComplete,
  FsFilterFastIoReadCompressed,
  FsFilterFastIoWriteCompressed,
  FsFilterFastIoMdlReadCompleteCompressed,
  FsFilterFastIoMdlWriteCompleteCompressed,
  FsFilterFastIoQueryOpen,
  NULL,
  NULL,
  NULL,
};

BOOLEAN is_block_namedpipe(IN PIO_STACK_LOCATION irpStack,IN PIRP Irp)
{
    switch(irpStack->MajorFunction)
    {
    case IRP_MJ_CREATE: //估计这里全是打开的操作.

        if(FlagOn(irpStack->FileObject->Flags,FO_NAMED_PIPE))
        {
            KdPrint(("FO_NAMED_PIPE!\n"));//这里没有拦截到.
        }

        if(Irp->IoStatus.Information == FILE_CREATED )//应该在完成后检测.
        {
            KdPrint(("named pipe FILE_CREATED!\n"));//这里没有拦截到.
        }

        /*
        检测到的名字有:操作是在桌面刷新一下.
        "\srvsvc"  这两个在对象管理器中没有找到.
        "\lsarpc"
        "\wkssvc"
        "\qqpcmgr\3_1_80" 这个估计是QQ电脑管家的.
        还有就是在我们的客户端测试程序拦截的,我们的东西"\mynamedpipe".
        */
        KdPrint(("named pipe name:%wZ\n",&(irpStack->FileObject->FileName)));

        break;
    case IRP_MJ_CREATE_NAMED_PIPE:
        KdPrint(("IRP_MJ_CREATE_NAMED_PIPE!\n"));//这里拦截到了,估计这里是创建的.用测试代码,也是创建操作在这里过.
        KdPrint(("create named pipe name:%wZ\n",&(irpStack->FileObject->FileName)));
        break;
    case IRP_MJ_READ:
        KdPrint(("NAMED PIPE READ!\n"));
        break;
    case IRP_MJ_WRITE:
        KdPrint(("NAMED PIPE WRITE!\n"));
        break;
    case IRP_MJ_SET_INFORMATION:
        KdPrint(("named pipe set information!\n"));//如果蓝屏,这是蓝屏后的最后一个消息,可是却蓝在读写函数或者控制上.
        break;
    default:
        KdPrint(("NAMED PIPE MajorFunction == %d!\n",irpStack->MajorFunction));
        break;
    }

    return FALSE;
}

BOOLEAN is_block_mailslot (IN PIO_STACK_LOCATION irpStack,IN PIRP Irp)
{
    switch(irpStack->MajorFunction)
    {
    case IRP_MJ_CREATE: //估计这里全是打开的操作.

        if (FlagOn(irpStack->FileObject->Flags,FO_MAILSLOT))
        {
            KdPrint(("FO_MAILSLOT!\n"));//这里没有拦截到.
        }

        if(Irp->IoStatus.Information == FILE_CREATED )//应该在完成后检测.
        {
            KdPrint(("mail slot FILE_CREATED!\n"));//这里没有拦截到.
        }

        KdPrint(("mail slot name:%wZ\n",&(irpStack->FileObject->FileName)));

        break;
    case IRP_MJ_CREATE_MAILSLOT:

        //打开局域网上的文件,发现了"\NET\GETDC042".

        KdPrint(("IRP_MJ_CREATE_MAILSLOT!\n"));//这里拦截到了,估计这里是创建的.
        KdPrint(("create mail slot name:%wZ\n",&(irpStack->FileObject->FileName)));
        break;
    case IRP_MJ_READ:
        KdPrint(("mail slot read!\n"));
        break;
    case IRP_MJ_WRITE:
        KdPrint(("mail slot write!\n"));
        break;
    case IRP_MJ_SET_INFORMATION:
        KdPrint(("mail slot set information!\n"));
        break;
    default:
        KdPrint(("mail slot MajorFunction == %d!\n",irpStack->MajorFunction));
        break;
    }

    return FALSE;
}

NTSTATUS PassThrough(IN PDEVICE_OBJECT pDO, IN PIRP Irp)
{
    PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
    PFILTER_DEVICE_EXTENSION pDevExt = (PFILTER_DEVICE_EXTENSION)pDO->DeviceExtension;
    BOOLEAN b = FALSE;
    NTSTATUS Status = STATUS_SUCCESS;

    PAGED_CODE();

    if (pDevExt->type == 'NPFS')
    {
        b = is_block_namedpipe(irpStack,Irp);
    } else if (pDevExt->type == 'MSFS')
    {
        b = is_block_mailslot (irpStack,Irp);
    } else {
        //CD0,这里可以有控制设备的处理.
    }

    //if (b)
    //{
    //    Irp->IoStatus.Status = STATUS_SUCCESS;
    //    Irp->IoStatus.Information = 0;

    //    IoCompleteRequest( Irp, IO_NO_INCREMENT );
    //    return STATUS_SUCCESS;
    //}
   
    IoSkipCurrentIrpStackLocation(Irp);
    Status = IoCallDriver(pDevExt->NextDeviceObject, Irp);//AttachedDevice
    if (!NT_SUCCESS(Status)) {
        KdPrint(("IoCallDriver fail %x!\n",Status));
        KdBreakPoint();
    }

    return Status;
}

VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
    PDEVICE_OBJECT preDeviceObject, CurrentDeviceObject;
    PFILTER_DEVICE_EXTENSION pDevExt;  

    PAGED_CODE();  

    preDeviceObject = DriverObject->DeviceObject;
    while (preDeviceObject != NULL)
    {
        pDevExt = (PFILTER_DEVICE_EXTENSION)preDeviceObject->DeviceExtension;  
        if (pDevExt->NextDeviceObject) { //确保本驱动创建的设备都包含PFILTER_DEVICE_EXTENSION,没有挂载的把此值设置为0.
            IoDetachDevice(pDevExt->NextDeviceObject);//反附加.AttachedDevice
        }

        CurrentDeviceObject = preDeviceObject;
        preDeviceObject = CurrentDeviceObject->NextDevice;
        IoDeleteDevice(CurrentDeviceObject);
    }
}

NTSTATUS AttachedDevice(wchar_t * pdevice,wchar_t * filter_device_name, int flag)
    /*
    功能:创建一个(过滤)设备并挂载到指定的设备上.
    参数说明:
    pdevice 被挂载的设备.
    filter_device_name 创建的过滤设备.
    flag 创建的过滤设备的标志,在设备对象的扩展结构里面.  

    失败的处理还不完善.需要改进.
    */
{
    NTSTATUS Status = STATUS_SUCCESS;
    UNICODE_STRING DeviceName;
    PDEVICE_OBJECT FilterDeviceObject;
    UNICODE_STRING ObjectName;
    PFILE_OBJECT FileObject;
    PDEVICE_OBJECT P_Target_DEVICE_OBJECT = 0;
    PFILTER_DEVICE_EXTENSION pDevExt = 0;
    PDEVICE_OBJECT  AttachedDevice = 0;
    PDEVICE_OBJECT      fileSysDevice;

    RtlInitUnicodeString(&ObjectName, pdevice);
    Status = IoGetDeviceObjectPointer(&ObjectName, FILE_ALL_ACCESS, &FileObject, &P_Target_DEVICE_OBJECT);
    if (Status != STATUS_SUCCESS) {
        KdPrint(("IoGetDeviceObjectPointer fail!\n"));
        KdBreakPoint();      
    }  

    ObDereferenceObject(FileObject);

    RtlInitUnicodeString( &DeviceName, filter_device_name);// NT_DEVICE_NAME  FILTER_DEVICE_NAME
    Status = IoCreateDevice(g_p_DriverObject, sizeof(FILTER_DEVICE_EXTENSION),&DeviceName, P_Target_DEVICE_OBJECT->DeviceType, 0, FALSE,&FilterDeviceObject);
    if (!NT_SUCCESS(Status)) {
        return Status;
    }
   
    ClearFlag(FilterDeviceObject->Flags, DO_DEVICE_INITIALIZING); //filterDeviceObject->Flags &= ~0x00000080;

    AttachedDevice = IoAttachDeviceToDeviceStack(FilterDeviceObject,  P_Target_DEVICE_OBJECT);//返回附加前的顶层设备.
    if (AttachedDevice == NULL) {
        KdPrint(("IoAttachDeviceToDeviceStack fail!\n"));  
        KdBreakPoint();
    }

    pDevExt = (PFILTER_DEVICE_EXTENSION)FilterDeviceObject->DeviceExtension;
    pDevExt->NextDeviceObject = AttachedDevice;
    pDevExt->type = flag;//        
   
    return TRUE;
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
    int i;
    NTSTATUS Status = STATUS_SUCCESS;
   
    UNREFERENCED_PARAMETER (RegistryPath);

    KdBreakPoint();//DbgBreakPoint()

    g_p_DriverObject = DriverObject;

    DriverObject->DriverUnload = DriverUnload;

    for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
        DriverObject->MajorFunction[i] = PassThrough;
    }

    DriverObject->FastIoDispatch = & g_fastIoDispatch;
   
    Status = AttachedDevice(L"\\Device\\NamedPipe", L"\\Device\\NPFS", 'NPFS');
    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    Status = AttachedDevice(L"\\Device\\Mailslot", L"\\Device\\MSFS", 'MSFS');
    if (!NT_SUCCESS(Status)) {
        //添加删除和反附加设备的代码.
        KdBreakPoint();  
    }

    return Status;
}

没有评论:

发表评论