手记

回顾驱动与用户层通信


环境:win10 64位

先关签名 有时这样不行 得去恢复 高级选项那禁止强制签名重启

bcdedit.exe /set nointegritychecks on

1。缓冲区方式读写 

桥梁是用一个buf

将数据存储在AssociatedIrp.SystemBuffer

pDevObj->Flags |= DO_BUFFERED_IO

用户层

main.cpp

#include <windows.h>

#include <stdio.h>

#define GetFilePointer(hFile) SetFilePointer(hFile, 0, NULL, FILE_CURRENT)

int main()

{

    HANDLE hDevice =

        CreateFile("\\\\.\\HelloDDK",

            GENERIC_READ | GENERIC_WRITE,

            0,      // share mode none

            NULL,   // no security

            OPEN_EXISTING,

            FILE_ATTRIBUTE_NORMAL,

            NULL);      // no template

    if (hDevice == INVALID_HANDLE_VALUE)

    {

        printf("Failed to obtain file handle to device: "

            "%s with Win32 error code: %d\n",

            "MyWDMDevice", GetLastError());

        //return 1;

    }

    UCHAR buffer[10];

    memset(buffer, 0xBB, 10);

    ULONG ulRead;

    ULONG ulWrite;

    BOOL bRet;

    bRet = WriteFile(hDevice, buffer, 10, &ulWrite, NULL);

    if (bRet)

    {

        printf("Write %d bytes\n", ulWrite);

    }

    bRet = ReadFile(hDevice, buffer, 10, &ulRead, NULL);

    if (bRet)

    {

        printf("Read %d bytes:", ulRead);

        for (int i = 0; i<(int)ulRead; i++)

        {

            printf("%02X ", buffer[i]);

        }

        printf("\n");

    }

    printf("file length:%d\n", GetFileSize(hDevice, NULL));

    CloseHandle(hDevice);

    getchar();

    return 0;

}

驱动层

test.c

#include "Driver.h"

/************************************************************************

* 函数名称:DriverEntry

* 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象

* 参数列表:

pDriverObject:从I/O管理器中传进来的驱动对象

pRegistryPath:驱动程序在注册表的中的路径

* 返回 值:返回初始化驱动状态

*************************************************************************/

#pragma INITCODE

 NTSTATUS DriverEntry(

    IN PDRIVER_OBJECT pDriverObject,

    IN PUNICODE_STRING pRegistryPath)

{

    NTSTATUS status;

    KdPrint(("Enter DriverEntry\n"));

    //设置卸载函数

    pDriverObject->DriverUnload = HelloDDKUnload;

    //设置派遣函数

    for (int i = 0; i < arraysize(pDriverObject->MajorFunction); ++i)

        pDriverObject->MajorFunction[i] = HelloDDKDispatchRoutin;

    pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDWrite;

    pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKRead;

    //用户层获取文件长度时用产生这个irp

    pDriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = HelloDDKQueryInfomation;

    //创建驱动设备对象

    status = CreateDevice(pDriverObject);

    KdPrint(("Leave DriverEntry\n"));

    return status;

}

/************************************************************************

* 函数名称:CreateDevice

* 功能描述:初始化设备对象

* 参数列表:

pDriverObject:从I/O管理器中传进来的驱动对象

* 返回 值:返回初始化状态

*************************************************************************/

#pragma INITCODE

NTSTATUS CreateDevice(

    IN PDRIVER_OBJECT   pDriverObject)

{

    NTSTATUS status;

    PDEVICE_OBJECT pDevObj;

    PDEVICE_EXTENSION pDevExt;

    //创建设备名称

    UNICODE_STRING devName;

    RtlInitUnicodeString(&devName, L"\\Device\\MyDDKDevice");

    //创建设备

    status = IoCreateDevice(pDriverObject,

        sizeof(DEVICE_EXTENSION),

        &devName,

        FILE_DEVICE_UNKNOWN,

        0, TRUE,

        &pDevObj);

    if (!NT_SUCCESS(status))

        return status;

    pDevObj->Flags |= DO_BUFFERED_IO;

    pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;

    pDevExt->pDevice = pDevObj;

    pDevExt->ustrDeviceName = devName;

    //申请模拟文件的缓冲区

    pDevExt->buffer = (PUCHAR)ExAllocatePool(PagedPool, MAX_FILE_LENGTH);

    //设置模拟文件大小

    pDevExt->file_length = 0;

    //创建符号链接

    UNICODE_STRING symLinkName;

    RtlInitUnicodeString(&symLinkName, L"\\??\\HelloDDK");

    pDevExt->ustrSymLinkName = symLinkName;

    status = IoCreateSymbolicLink(&symLinkName, &devName);

    if (!NT_SUCCESS(status))

    {

        IoDeleteDevice(pDevObj);

        return status;

    }

    return STATUS_SUCCESS;

}

/************************************************************************

* 函数名称:HelloDDKUnload

* 功能描述:负责驱动程序的卸载操作

* 参数列表:

pDriverObject:驱动对象

* 返回 值:返回状态

*************************************************************************/

#pragma PAGEDCODE

VOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject)

{

    PDEVICE_OBJECT  pNextObj;

    KdPrint(("Enter DriverUnload\n"));

    pNextObj = pDriverObject->DeviceObject;

    while (pNextObj != NULL)

    {

        PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)

            pNextObj->DeviceExtension;

        if (pDevExt->buffer)

        {

            ExFreePool(pDevExt->buffer);

            pDevExt->buffer = NULL;

        }

        //删除符号链接

        UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;

        IoDeleteSymbolicLink(&pLinkName);

        pNextObj = pNextObj->NextDevice;

        IoDeleteDevice(pDevExt->pDevice);

    }

}

/************************************************************************

* 函数名称:HelloDDKDispatchRoutin

* 功能描述:对读IRP进行处理

* 参数列表:

pDevObj:功能设备对象

pIrp:从IO请求包

* 返回 值:返回状态

*************************************************************************/

#pragma PAGEDCODE

NTSTATUS HelloDDKDispatchRoutin(IN PDEVICE_OBJECT pDevObj,

    IN PIRP pIrp)

{

    KdPrint(("Enter HelloDDKDispatchRoutin\n"));

    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);

    //建立一个字符串数组与IRP类型对应起来

    static char* irpname[] =

    {

        "IRP_MJ_CREATE",

        "IRP_MJ_CREATE_NAMED_PIPE",

        "IRP_MJ_CLOSE",

        "IRP_MJ_READ",

        "IRP_MJ_WRITE",

        "IRP_MJ_QUERY_INFORMATION",

        "IRP_MJ_SET_INFORMATION",

        "IRP_MJ_QUERY_EA",

        "IRP_MJ_SET_EA",

        "IRP_MJ_FLUSH_BUFFERS",

        "IRP_MJ_QUERY_VOLUME_INFORMATION",

        "IRP_MJ_SET_VOLUME_INFORMATION",

        "IRP_MJ_DIRECTORY_CONTROL",

        "IRP_MJ_FILE_SYSTEM_CONTROL",

        "IRP_MJ_DEVICE_CONTROL",

        "IRP_MJ_INTERNAL_DEVICE_CONTROL",

        "IRP_MJ_SHUTDOWN",

        "IRP_MJ_LOCK_CONTROL",

        "IRP_MJ_CLEANUP",

        "IRP_MJ_CREATE_MAILSLOT",

        "IRP_MJ_QUERY_SECURITY",

        "IRP_MJ_SET_SECURITY",

        "IRP_MJ_POWER",

        "IRP_MJ_SYSTEM_CONTROL",

        "IRP_MJ_DEVICE_CHANGE",

        "IRP_MJ_QUERY_QUOTA",

        "IRP_MJ_SET_QUOTA",

        "IRP_MJ_PNP",

    };

    UCHAR type = stack->MajorFunction;

    if (type >= arraysize(irpname))

        KdPrint((" - Unknown IRP, major type %X\n", type));

    else

        KdPrint(("\t%s\n", irpname[type]));

    //对一般IRP的简单操作,后面会介绍对IRP更复杂的操作

    NTSTATUS status = STATUS_SUCCESS;

    // 完成IRP

    pIrp->IoStatus.Status = status;

    pIrp->IoStatus.Information = 0; // bytes xfered

    IoCompleteRequest(pIrp, IO_NO_INCREMENT);

    KdPrint(("Leave HelloDDKDispatchRoutin\n"));

    return status;

}

NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,

    IN PIRP pIrp)

{

    KdPrint(("Enter HelloDDKRead\n"));

    //在 IoCreateDevice申请模拟文件的缓冲区

    //pDevExt->buffer = (PUCHAR)ExAllocatePool(PagedPool, MAX_FILE_LENGTH);

    PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;

    NTSTATUS status = STATUS_SUCCESS;

    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);

    ULONG ulReadLength = stack->Parameters.Read.Length;

    ULONG ulReadOffset = (ULONG)stack->Parameters.Read.ByteOffset.QuadPart;

    if (ulReadOffset + ulReadLength>MAX_FILE_LENGTH)

    {

        status = STATUS_FILE_INVALID;

        ulReadLength = 0;

    }

    else

    {

        //将数据存储在AssociatedIrp.SystemBuffer,以便应用程序使用

        memcpy(pIrp->AssociatedIrp.SystemBuffer, pDevExt->buffer + ulReadOffset, ulReadLength);

        status = STATUS_SUCCESS;

    }

    pIrp->IoStatus.Status = status;

    pIrp->IoStatus.Information = ulReadLength;  // bytes xfered

    IoCompleteRequest(pIrp, IO_NO_INCREMENT);

    KdPrint(("Leave HelloDDKRead\n"));

    return status;

}

NTSTATUS HelloDDWrite(IN PDEVICE_OBJECT pDevObj,

    IN PIRP pIrp)

{

    KdPrint(("Enter HelloDDWrite\n"));

    NTSTATUS status = STATUS_SUCCESS;

    //在 IoCreateDevice申请模拟文件的缓冲区

    //pDevExt->buffer = (PUCHAR)ExAllocatePool(PagedPool, MAX_FILE_LENGTH);

    PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;

    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);

    //获取存储的长度

    ULONG ulWriteLength = stack->Parameters.Write.Length;

    //获取存储的偏移量 就是buffer中从哪里开始

    ULONG ulWriteOffset = (ULONG)stack->Parameters.Write.ByteOffset.QuadPart;

    if (ulWriteOffset + ulWriteLength>MAX_FILE_LENGTH)

    {

        //如果存储长度+偏移量大于缓冲区长度,则返回无效

        status = STATUS_FILE_INVALID;

        ulWriteLength = 0;

    }

    else

    {

        //将写入的数据,存储在缓冲区内

        memcpy(pDevExt->buffer + ulWriteOffset, pIrp->AssociatedIrp.SystemBuffer, ulWriteLength);

        status = STATUS_SUCCESS;

        //设置新的文件长度

        if (ulWriteLength + ulWriteOffset>pDevExt->file_length)

        {

            pDevExt->file_length = ulWriteLength + ulWriteOffset;

        }

    }

    pIrp->IoStatus.Status = status;

    //用户的返回值是这个

    pIrp->IoStatus.Information = ulWriteLength; // bytes xfered

    IoCompleteRequest(pIrp, IO_NO_INCREMENT);

    KdPrint(("Leave HelloDDWrite\n"));

    return status;

}

NTSTATUS HelloDDKQueryInfomation(IN PDEVICE_OBJECT pDevObj,

    IN PIRP pIrp)

{

    KdPrint(("Enter HelloDDKQueryInfomation\n"));

    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);

    PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;

    FILE_INFORMATION_CLASS info = stack->Parameters.QueryFile.FileInformationClass;

    if (info == FileStandardInformation)

    {

        KdPrint(("FileStandardInformation\n"));

        PFILE_STANDARD_INFORMATION file_info =

            (PFILE_STANDARD_INFORMATION)pIrp->AssociatedIrp.SystemBuffer;

        file_info->EndOfFile = RtlConvertLongToLargeInteger(pDevExt->file_length);

    }

    NTSTATUS status = STATUS_SUCCESS;

    // 完成IRP

    pIrp->IoStatus.Status = status;

    pIrp->IoStatus.Information = stack->Parameters.QueryFile.Length;    // bytes xfered

    IoCompleteRequest(pIrp, IO_NO_INCREMENT);

    KdPrint(("Leave HelloDDKQueryInfomation\n"));

    return status;

}

//Driver.h

#pragma once

#ifdef __cplusplus

extern "C"

{

#endif

#include <NTDDK.h>

#ifdef __cplusplus

}

#endif 

#define PAGEDCODE code_seg("PAGE")

#define LOCKEDCODE code_seg()

#define INITCODE code_seg("INIT")

#define PAGEDDATA data_seg("PAGE")

#define LOCKEDDATA data_seg()

#define INITDATA data_seg("INIT")

#define arraysize(p) (sizeof(p)/sizeof((p)[0]))

#define MAX_FILE_LENGTH 1024

typedef struct _DEVICE_EXTENSION {

    PDEVICE_OBJECT pDevice;

    UNICODE_STRING ustrDeviceName;  //设备名称

    UNICODE_STRING ustrSymLinkName; //符号链接名

    PUCHAR buffer;//缓冲区

    ULONG file_length;//模拟的文件长度,必须小于MAX_FILE_LENGTH

} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

// 函数声明

NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject);

VOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject);

NTSTATUS HelloDDKDispatchRoutin(IN PDEVICE_OBJECT pDevObj,

    IN PIRP pIrp);

NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,

    IN PIRP pIrp);

NTSTATUS HelloDDWrite(IN PDEVICE_OBJECT pDevObj,

    IN PIRP pIrp);

NTSTATUS HelloDDKQueryInfomation(IN PDEVICE_OBJECT pDevObj,

    IN PIRP pIrp);

回顾驱动与用户层通信

2。直接方式

pDevObj->Flags |= DO_DIRECT_IO;

用户层

main.cpp

#include <windows.h>

#include <stdio.h>

#define GetFilePointer(hFile) SetFilePointer(hFile, 0, NULL, FILE_CURRENT)

int main()

{

    HANDLE hDevice = 

        CreateFile("\\\\.\\HelloDDK",

                    GENERIC_READ | GENERIC_WRITE,

                    0,      // share mode none

                    NULL,   // no security

                    OPEN_EXISTING,

                    FILE_ATTRIBUTE_NORMAL,

                    NULL );     // no template

    if (hDevice == INVALID_HANDLE_VALUE)

    {

        printf("Failed to obtain file handle to device: "

            "%s with Win32 error code: %d\n",

            "MyWDMDevice", GetLastError() );

        return 1;

    }

    UCHAR buffer[10];

    memset(buffer,0xBB,10);

    ULONG ulRead;

    BOOL bRet;

    bRet = ReadFile(hDevice,buffer,10,&ulRead,NULL);

    if (bRet)

    {

        printf("Address 0X%08X\n",buffer);

        printf("(Read %d bytes):",ulRead);

        for (int i=0;i<(int)ulRead;i++)

        {

            printf("%02X ",buffer[i]);

        }

        printf("\n");

    }

    CloseHandle(hDevice);

    return 0;

}

驱动层

test.c

#include "Driver.h"

/************************************************************************

* 函数名称:DriverEntry

* 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象

* 参数列表:

      pDriverObject:从I/O管理器中传进来的驱动对象

      pRegistryPath:驱动程序在注册表的中的路径

* 返回 值:返回初始化驱动状态

*************************************************************************/

#pragma INITCODE

 NTSTATUS DriverEntry (

            IN PDRIVER_OBJECT pDriverObject,

            IN PUNICODE_STRING pRegistryPath    ) 

{

    NTSTATUS status;

    KdPrint(("Enter DriverEntry\n"));

    //设置卸载函数

    pDriverObject->DriverUnload = HelloDDKUnload;

    //设置派遣函数

    for (int i = 0; i < arraysize(pDriverObject->MajorFunction); ++i)

        pDriverObject->MajorFunction[i] = HelloDDKDispatchRoutin;

    pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKRead;

    //创建驱动设备对象

    status = CreateDevice(pDriverObject);

    KdPrint(("Leave DriverEntry\n"));

    return status;

}

/************************************************************************

* 函数名称:CreateDevice

* 功能描述:初始化设备对象

* 参数列表:

      pDriverObject:从I/O管理器中传进来的驱动对象

* 返回 值:返回初始化状态

*************************************************************************/

#pragma INITCODE

NTSTATUS CreateDevice (

        IN PDRIVER_OBJECT   pDriverObject) 

{

    NTSTATUS status;

    PDEVICE_OBJECT pDevObj;

    PDEVICE_EXTENSION pDevExt;

    //创建设备名称

    UNICODE_STRING devName;

    RtlInitUnicodeString(&devName,L"\\Device\\MyDDKDevice");

    //创建设备

    status = IoCreateDevice( pDriverObject,

                        sizeof(DEVICE_EXTENSION),

                        &(UNICODE_STRING)devName,

                        FILE_DEVICE_UNKNOWN,

                        0, TRUE,

                        &pDevObj );

    if (!NT_SUCCESS(status))

        return status;

    pDevObj->Flags |= DO_DIRECT_IO;

    pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;

    pDevExt->pDevice = pDevObj;

    pDevExt->ustrDeviceName = devName;

    //申请模拟文件的缓冲区

    pDevExt->buffer = (PUCHAR)ExAllocatePool(PagedPool,MAX_FILE_LENGTH);

    //设置模拟文件大小

    pDevExt->file_length = 0;

    //创建符号链接

    UNICODE_STRING symLinkName;

    RtlInitUnicodeString(&symLinkName,L"\\??\\HelloDDK");

    pDevExt->ustrSymLinkName = symLinkName;

    status = IoCreateSymbolicLink( &symLinkName,&devName );

    if (!NT_SUCCESS(status)) 

    {

        IoDeleteDevice( pDevObj );

        return status;

    }

    return STATUS_SUCCESS;

}

/************************************************************************

* 函数名称:HelloDDKUnload

* 功能描述:负责驱动程序的卸载操作

* 参数列表:

      pDriverObject:驱动对象

* 返回 值:返回状态

*************************************************************************/

#pragma PAGEDCODE

VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject) 

{

    PDEVICE_OBJECT  pNextObj;

    KdPrint(("Enter DriverUnload\n"));

    pNextObj = pDriverObject->DeviceObject;

    while (pNextObj != NULL) 

    {

        PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)

            pNextObj->DeviceExtension;

        if (pDevExt->buffer)

        {

            ExFreePool(pDevExt->buffer);

            pDevExt->buffer = NULL;

        }

        //删除符号链接

        UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;

        IoDeleteSymbolicLink(&pLinkName);

        pNextObj = pNextObj->NextDevice;

        IoDeleteDevice( pDevExt->pDevice );

    }

}

/************************************************************************

* 函数名称:HelloDDKDispatchRoutin

* 功能描述:对读IRP进行处理

* 参数列表:

      pDevObj:功能设备对象

      pIrp:从IO请求包

* 返回 值:返回状态

*************************************************************************/

#pragma PAGEDCODE

NTSTATUS HelloDDKDispatchRoutin(IN PDEVICE_OBJECT pDevObj,

                                 IN PIRP pIrp) 

{

    KdPrint(("Enter HelloDDKDispatchRoutin\n"));

    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);

    //建立一个字符串数组与IRP类型对应起来

    static char* irpname[] = 

    {

        "IRP_MJ_CREATE",

        "IRP_MJ_CREATE_NAMED_PIPE",

        "IRP_MJ_CLOSE",

        "IRP_MJ_READ",

        "IRP_MJ_WRITE",

        "IRP_MJ_QUERY_INFORMATION",

        "IRP_MJ_SET_INFORMATION",

        "IRP_MJ_QUERY_EA",

        "IRP_MJ_SET_EA",

        "IRP_MJ_FLUSH_BUFFERS",

        "IRP_MJ_QUERY_VOLUME_INFORMATION",

        "IRP_MJ_SET_VOLUME_INFORMATION",

        "IRP_MJ_DIRECTORY_CONTROL",

        "IRP_MJ_FILE_SYSTEM_CONTROL",

        "IRP_MJ_DEVICE_CONTROL",

        "IRP_MJ_INTERNAL_DEVICE_CONTROL",

        "IRP_MJ_SHUTDOWN",

        "IRP_MJ_LOCK_CONTROL",

        "IRP_MJ_CLEANUP",

        "IRP_MJ_CREATE_MAILSLOT",

        "IRP_MJ_QUERY_SECURITY",

        "IRP_MJ_SET_SECURITY",

        "IRP_MJ_POWER",

        "IRP_MJ_SYSTEM_CONTROL",

        "IRP_MJ_DEVICE_CHANGE",

        "IRP_MJ_QUERY_QUOTA",

        "IRP_MJ_SET_QUOTA",

        "IRP_MJ_PNP",

    };

    UCHAR type = stack->MajorFunction;

    if (type >= arraysize(irpname))

        KdPrint((" - Unknown IRP, major type %X\n", type));

    else

        KdPrint(("\t%s\n", irpname[type]));

    NTSTATUS status = STATUS_SUCCESS;

    // 完成IRP

    pIrp->IoStatus.Status = status;

    pIrp->IoStatus.Information = 0; // bytes xfered

    IoCompleteRequest( pIrp, IO_NO_INCREMENT );

    KdPrint(("Leave HelloDDKDispatchRoutin\n"));

    return status;

}

NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,

                                 IN PIRP pIrp) 

{

    KdPrint(("Enter HelloDDKRead\n"));

    PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;

    NTSTATUS status = STATUS_SUCCESS;

    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);

    ULONG ulReadLength = stack->Parameters.Read.Length;

    KdPrint(("ulReadLength:%d\n",ulReadLength));

    ULONG mdl_length = MmGetMdlByteCount(pIrp->MdlAddress);

    PVOID mdl_address = MmGetMdlVirtualAddress(pIrp->MdlAddress);

    ULONG mdl_offset = MmGetMdlByteOffset(pIrp->MdlAddress);

    KdPrint(("mdl_address:0X%08X\n",mdl_address));

    KdPrint(("mdl_length:%d\n",mdl_length));

    KdPrint(("mdl_offset:%d\n",mdl_offset));

    if (mdl_length!=ulReadLength)

    {

        //MDL的长度应该和读长度相等,否则该操作应该设为不成功

        pIrp->IoStatus.Information = 0;

        status = STATUS_UNSUCCESSFUL;

    }else

    {

        //用MmGetSystemAddressForMdlSafe得到MDL在内核模式下的映射 就是用户中的buffer映射

        PVOID kernel_address = MmGetSystemAddressForMdlSafe(pIrp->MdlAddress,NormalPagePriority);

        KdPrint(("kernel_address:0X%08X\n",kernel_address));

        //修改数据

        memset(kernel_address,0XAA,ulReadLength);

        pIrp->IoStatus.Information = ulReadLength;  // bytes xfered

    }

    pIrp->IoStatus.Status = status;

    IoCompleteRequest( pIrp, IO_NO_INCREMENT );

    KdPrint(("Leave HelloDDKRead\n"));

    return status;

}

//Driver.h

/************************************************************************

* 文件名称:Driver.h                                                 

* 作    者:张帆

* 完成日期:2007-11-1

*************************************************************************/

#pragma once

#ifdef __cplusplus

extern "C"

{

#endif

#include <NTDDK.h>

#ifdef __cplusplus

}

#endif 

#define PAGEDCODE code_seg("PAGE")

#define LOCKEDCODE code_seg()

#define INITCODE code_seg("INIT")

#define PAGEDDATA data_seg("PAGE")

#define LOCKEDDATA data_seg()

#define INITDATA data_seg("INIT")

#define arraysize(p) (sizeof(p)/sizeof((p)[0]))

#define MAX_FILE_LENGTH 1024

typedef struct _DEVICE_EXTENSION {

    PDEVICE_OBJECT pDevice;

    UNICODE_STRING ustrDeviceName;  //设备名称

    UNICODE_STRING ustrSymLinkName; //符号链接名

    PUCHAR buffer;//缓冲区

    ULONG file_length;//模拟的文件长度,必须小于MAX_FILE_LENGTH

} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

// 函数声明

NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject);

VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject);

NTSTATUS HelloDDKDispatchRoutin(IN PDEVICE_OBJECT pDevObj,

                                 IN PIRP pIrp);

NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,

                                 IN PIRP pIrp);

NTSTATUS HelloDDWrite(IN PDEVICE_OBJECT pDevObj,

                                 IN PIRP pIrp);

NTSTATUS HelloDDKQueryInfomation(IN PDEVICE_OBJECT pDevObj,

                                 IN PIRP pIrp);

©著作权归作者所有:来自51CTO博客作者土匪猿的原创作品,如需转载,请注明出处,否则将追究法律责任


0人推荐
随时随地看视频
慕课网APP