首页
社区
课程
招聘
[分享]experiment : test wdk's cdo sample in minifilter
发表于: 2013-7-17 18:55 5422

[分享]experiment : test wdk's cdo sample in minifilter

2013-7-17 18:55
5422
WDK中有在minifilter中使用CDO来通讯(r3 <=> r0)的例子 CDO

工程位置 :  \WinDDK\7600.16385.1\src\filesys\miniFilter\cdo

 增加了r3测试程序用来通讯, 控制码的设备类型 应为 FILE_DEVICE_FILE_SYSTEM

/// @file       AppCommunicationWithDrv.cpp
/// @brief      测试与 cdo.sys(Wdk Sample) 通讯, 使用 DeviceIoControl
///             cdo's project : \WinDDK\7600.16385.1\src\filesys\miniFilter\cdo

#include "stdafx.h"
#include <windows.h>
#include <time.h>

#define DRIVER_NAME L"\\\\?\\GLOBALROOT\\FileSystem\\Filters\\CdoSample"

/// 要从大一点的数开始, 系统自定义的IO控制码用了一些
#define FUNCTION_CDO_BASE       0x800

/// 测试与CDO之间的通讯(IRP_MJ_FILE_SYSTEM_CONTROL)
#define FUNCTION_CDO_TEST_FS    (FUNCTION_CDO_BASE + 1)

/// CTL_CODE First Parameter is DeviceType
/// winioctl.h define DeviceType, see readme.txt

/// test FILE_DEVICE_FILE_SYSTEM
#define DRV_COMMAND_CDO_TEST_FS \
    CTL_CODE(FILE_DEVICE_FILE_SYSTEM, \
    FUNCTION_CDO_TEST_FS, \
    METHOD_BUFFERED, \
    FILE_READ_ACCESS | FILE_WRITE_ACCESS)

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE  hFile       =   INVALID_HANDLE_VALUE;
    DWORD   dwBufIn     =   0;
    DWORD   dwBufOut    =   0;
    DWORD   dwLenOut    =   0;

    hFile = ::CreateFile(
        DRIVER_NAME,
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL );

    if (INVALID_HANDLE_VALUE == hFile)
    {
        _tprintf(L"(INVALID_HANDLE_VALUE == hHandle), LastError = 0x%X\r\n", 
            GetLastError());
        goto _tmain_END;
    }

    srand((unsigned)time(NULL));
    dwBufIn = rand();
    if (!DeviceIoControl(hFile,
        DRV_COMMAND_CDO_TEST_FS,
        &dwBufIn,
        sizeof(DWORD),
        &dwBufOut,
        sizeof(DWORD),
        &dwLenOut,
        NULL))
    {
        _tprintf(L"(TRUE != DeviceIoControl), "
            L"DRV_COMMAND_CDO_TEST_FS LastError = 0x%X\r\n", 
            GetLastError());
        goto _tmain_END;
    }

    _tprintf(L"dwBufIn = 0x%X, dwBufOut = 0x%X\r\n", dwBufIn, dwBufOut);

    ::CloseHandle(hFile);
    _tprintf(L"test OK\r\n");

_tmain_END:
    _tprintf(L"END, press any key to quit\r\n");
    getwchar();
    return 0;
}


r0程序为了调试和验证, 改了一点.
/// on pch.h
#ifndef DWORD
#define DWORD   ULONG
#endif


/// on cdoinit.c
VOID CdoInitializeDebugLevel (
    __in PUNICODE_STRING RegistryPath
    )
/*++

Routine Description:

    This routine tries to read the filter DebugLevel parameter from 
    the registry.  This value will be found in the registry location
    indicated by the RegistryPath passed in.

Arguments:

    RegistryPath - The path key passed to the driver during DriverEntry.
        
Return Value:

    None.

--*/
{
    OBJECT_ATTRIBUTES attributes;
    HANDLE driverRegKey;
    NTSTATUS status;
    ULONG resultLength;
    UNICODE_STRING valueName;
    UCHAR buffer[sizeof( KEY_VALUE_PARTIAL_INFORMATION ) + sizeof( LONG )];

    Globals.DebugLevel = DEBUG_TRACE_ALL;   // DEBUG_TRACE_ERROR;
    return;


/// On CdoOperations.c
NTSTATUS
CdoHandlePrivateFsControl (
    __in PDEVICE_OBJECT DeviceObject,
    __in ULONG IoControlCode,
    __in_bcount_opt(InputBufferLength) PVOID InputBuffer,
    __in ULONG InputBufferLength,
    __out_bcount_opt(OutputBufferLength) PVOID OutputBuffer,
    __in ULONG OutputBufferLength,
    __out PIO_STATUS_BLOCK IoStatus,
    __in_opt PIRP Irp
    )
/*++

Routine Description:

    This routine is invoked whenever an I/O Request Packet (IRP) w/a major
    function code of IRP_MJ_FILE_SYSTEM_CONTROL is encountered for the CDO.

Arguments:

    DeviceObject        - Pointer to the device object for this driver.
    IoControlCode       - Control code for this IOCTL
    InputBuffer         - Input buffer
    InputBufferLength   - Input buffer length
    OutputBuffer        - Output buffer
    OutputBufferLength  - Output buffer length
    IoStatus            - IO status block for this request
    Irp - Pointer to the request packet representing the I/O request.

Return Value:

    The function value is the status of the operation.

--*/
{
    NTSTATUS status = STATUS_SUCCESS;

    UNREFERENCED_PARAMETER( DeviceObject );
    UNREFERENCED_PARAMETER( IoControlCode );
    UNREFERENCED_PARAMETER( InputBuffer );
    UNREFERENCED_PARAMETER( InputBufferLength );
    UNREFERENCED_PARAMETER( OutputBuffer );
    UNREFERENCED_PARAMETER( OutputBufferLength );
    UNREFERENCED_PARAMETER( Irp );

    PAGED_CODE();

    DebugTrace( DEBUG_TRACE_CDO_SUPPORTED_OPERATIONS,
                ("[Cdo]: CdoHandlePrivateFsControl entry ( Irp = %p )\n"
                 "\tIoControlCode = 0x%x\n"
                 "\tInputBuffer = %p\n"
                 "\tInputBufferLength = 0x%x\n"
                 "\tOutputBuffer = %p\n"
                 "\tOutputBufferLength = 0x%x\n",
                 Irp,
                 IoControlCode,
                 InputBuffer,
                 InputBufferLength,
                 OutputBuffer,
                 OutputBufferLength) );

    CdoAcquireResourceShared( &Globals.Resource );
    
    IoStatus->Status = status;
    IoStatus->Information = 0;
    
    //
    //  Sanity - there must atleast be a reference open for us to get a IOCTL on the CDO
    //

    ASSERT( FlagOn( Globals.Flags, GLOBAL_DATA_F_CDO_OPEN_REF ) );


    if (!FlagOn( Globals.Flags, GLOBAL_DATA_F_CDO_OPEN_HANDLE)) {

        //
        //  If there is no handle open to the CDO fail the operation
        //

        DebugTrace( DEBUG_TRACE_CDO_SUPPORTED_OPERATIONS | DEBUG_TRACE_ERROR,
                    ("[Cdo]: CdoHandlePrivateFsControl -> Failing IOCTL since no handle to CDO is open. ( Irp = %p, IoControlCode = 0x%x, Flags = 0x%x )\n",
                     Irp,
                     IoControlCode,
                     Globals.Flags) );

        status = STATUS_INVALID_DEVICE_STATE;
        CdoReleaseResource( &Globals.Resource );
        goto CdoHandlePrivateFsControlCleanup;
    }

    //
    //  Here the filter may perform any action that requires that
    //  the handle to the CDO still be open

    DebugTrace( DEBUG_TRACE_CDO_SUPPORTED_OPERATIONS,
                ("[Cdo]: CdoHandlePrivateFsControl -> Processing IOCTL while handle to CDO is definitely open. ( Irp = %p, IoControlCode = 0x%x )\n",
                 Irp,
                 IoControlCode) );

    
    /// 假设的回答是: 输出参数 = 输入参数 + 1
    if ((NULL != OutputBuffer)
        && (NULL != InputBuffer)
        && (InputBufferLength >= sizeof(DWORD))
        && (OutputBufferLength >= sizeof(DWORD)))
        {
            *((DWORD *)OutputBuffer) = *((DWORD *)InputBuffer) + 1;
            IoStatus->Status = STATUS_SUCCESS;
            IoStatus->Information = sizeof(DWORD);
        }
    else
        {
            IoStatus->Status = STATUS_INVALID_PARAMETER;
            IoStatus->Information = 0;
        }
    
    CdoReleaseResource( &Globals.Resource );

    //
    //  Since the resource has been released the CDO may complete a cleanup before we
    //  do any of the following.
    //


    //
    //  Here the filter may perform any action that does not require that
    //  the handle to the CDO still be open. For example, the IOCTL may have
    //  been used to trigger off an asynchronous background task that will
    //  continue executing even after the handle has been closed
    //
    //  Note that the system will still maintain a reference to the CDO. So,
    //  the filter will not see a Close on the CDO until it finishes servicing
    //  IRP_MJ_FILE_SYSTEM_CONTROL
    //

    DebugTrace( DEBUG_TRACE_CDO_SUPPORTED_OPERATIONS,
                ("[Cdo]: CdoHandlePrivateFsControl -> Processing IOCTL while handle to CDO may not be open. ( Irp = %p, IoControlCode = 0x%x )\n",
                 Irp,
                 IoControlCode) );

    status = STATUS_SUCCESS;

CdoHandlePrivateFsControlCleanup:
    DebugTrace( DEBUG_TRACE_CDO_SUPPORTED_OPERATIONS,
                ("[Cdo]: CdoHandlePrivateFsControl exit ( Irp = %p, IoControlCode = 0x%x, status = 0x%x )\n",
                 Irp,
                 IoControlCode,
                 status) );

    return status;
}


用程序加载minifilter驱动后, 安装, 启动.

运行r3测试程序, 通过WinDbg单步驱动和看测试程序的结果, 表明r3和r0通讯成功.


测试中用到的工具:  PCHunter, DevieTree,  InstMiniDrv

  测试环境: winXpSp3

试验用的工程:  CDO测试工程.rar

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 74
活跃值: (748)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
来学习下~
2013-7-18 09:17
0
游客
登录 | 注册 方可回帖
返回
//