内核层

#include <ntddk.h>
#include <windef.h>typedef struct _DEVICE_EXTENSION
{PCHAR Buffer;//内存首地址ULONG Length;//文件长度
#define MAX_FILE_LEN 4096
}DEVICE_EXTENSION, *PDEVICE_EXTENSION;VOID Unload(IN PDRIVER_OBJECT pDriverObject)
{UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\HelloDDK");IoDeleteSymbolicLink(&SymbolicLinkName);//删除连接IoDeleteDevice(pDriverObject->DeviceObject);//释放驱动对象//驱动卸载的时候显示KdPrint(("Goodbye driver\n"));
}NTSTATUS DispatchRoutine(IN PDEVICE_OBJECT deviceObject, IN 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                     ","IRP_MJ_PNP_POWER               ","IRP_MJ_MAXIMUM_FUNCTION        "};PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);//获取当前栈单元KdPrint(("%s\n", irpname[stack->MajorFunction]));Irp->IoStatus.Information = 0;Irp->IoStatus.Status = STATUS_SUCCESS;//设置返回状态,告诉操作是成功还是失败IoCompleteRequest(Irp, IO_NO_INCREMENT);//是不改变return STATUS_SUCCESS;
};
//其他方式读取
NTSTATUS NeitherRead(IN PDEVICE_OBJECT deviceObject, IN PIRP Irp)
{NTSTATUS status = STATUS_SUCCESS;ULONG Length;PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);__try{ProbeForWrite(Irp->UserBuffer, stack->Parameters.Read.Length, 4);Length = strlen("这是一段来自内核地址空间的数据");RtlCopyMemory(Irp->UserBuffer, "这是一段来自内核地址空间的数据", Length);}__except (EXCEPTION_EXECUTE_HANDLER){status = GetExceptionCode();Length = 0;}Irp->IoStatus.Status = status;//设置返回状态,告诉操作是成功还是失败Irp->IoStatus.Information = 0;IoCompleteRequest(Irp, IO_NO_INCREMENT);//是不改变return status;
}
//mdl直接方式读取
NTSTATUS DirectRead(IN PDEVICE_OBJECT deviceObject, IN PIRP Irp)
{KdPrint(("进入DirectRead:\n"));NTSTATUS status = STATUS_SUCCESS;PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);PCHAR Buffer;ULONG ByteOffset;ULONG ByteCount;ULONG Length;PVOID Va;__try{ByteOffset = MmGetMdlByteCount(Irp->MdlAddress);ByteCount = MmGetMdlByteCount(Irp->MdlAddress);Va = MmGetMdlVirtualAddress(Irp->MdlAddress);KdPrint(("ByteOffset:%d\n", ByteOffset));KdPrint(("ByteCount:%d\n", ByteCount));KdPrint(("用户空间地址:%p\n", Va));Buffer = (PCHAR)MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);if (stack->Parameters.Read.Length <= ByteCount){Length = strlen("这是一段来自内核地址空间的数据");RtlCopyMemory(Buffer, "这是一段来自内核地址空间的数据", Length);}else {status = STATUS_UNSUCCESSFUL;Length = 0;}}__except (EXCEPTION_EXECUTE_HANDLER){status = GetExceptionCode();Length = 0;}Irp->IoStatus.Status = status;//设置返回状态,告诉操作是成功还是失败Irp->IoStatus.Information = 0;IoCompleteRequest(Irp, IO_NO_INCREMENT);//是不改变return status;
}//首先不能超过内存块,在内存卡之内我写的文件长度,超过文件长度就需要更新文件长度,不超过文件长度保持不变
NTSTATUS DispatchWrite(IN PDEVICE_OBJECT deviceObject, IN PIRP Irp)
{NTSTATUS status = STATUS_SUCCESS;PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);//获取当前栈单元PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;ULONG Length;ULONG offset;ULONG WriteLenth;//写出的实际长度KdPrint(("写操作\n"));__try{Length = stack->Parameters.Write.Length;offset = stack->Parameters.Write.ByteOffset.LowPart;if (Length + offset <= MAX_FILE_LEN){if (Length + offset > pdx->Length){//更新文件长度pdx->Length = Length + offset;}RtlCopyMemory(pdx->Buffer + offset, Irp->AssociatedIrp.SystemBuffer, Length);WriteLenth = Length;}else{status = STATUS_BUFFER_TOO_SMALL;//缓冲区太小的错误WriteLenth = 0;}}__except (EXCEPTION_EXECUTE_HANDLER){status = GetExceptionCode();WriteLenth = 0;}Irp->IoStatus.Status = status;Irp->IoStatus.Information = WriteLenth;IoCompleteRequest(Irp, IO_NO_INCREMENT);//是不改变return status;
}NTSTATUS DispatchQueryInfo(IN PDEVICE_OBJECT deviceObject, IN PIRP Irp)
{NTSTATUS status;PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);//获取当前栈单元ULONG Length;KdPrint(("查操作\n"));__try{Length = stack->Parameters.QueryFile.Length;if (stack->Parameters.QueryFile.FileInformationClass == FileStandardInformation &&Length >= sizeof(FILE_STANDARD_INFORMATION)){PFILE_STANDARD_INFORMATION  pfsi = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer;pfsi->EndOfFile.LowPart = pdx->Length;status = STATUS_SUCCESS;Length = sizeof(FILE_STANDARD_INFORMATION);}else{status = STATUS_BUFFER_TOO_SMALL;Length = 0;}}__except (EXCEPTION_EXECUTE_HANDLER){status = GetExceptionCode();Length = 0;}Irp->IoStatus.Status = status;Irp->IoStatus.Information = Length;IoCompleteRequest(Irp, IO_NO_INCREMENT);//是不改变return status;
}extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\HelloDDK");UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\HelloDDK");NTSTATUS status;PDEVICE_OBJECT DeviceObject;PDEVICE_EXTENSION pdx;ULONG i = 0;KdPrint(("Hello driver\n"));DriverObject->DriverUnload = Unload;for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION + 1; i++){DriverObject->MajorFunction[i] = DispatchRoutine;}//读操作DriverObject->MajorFunction[IRP_MJ_READ] = DirectRead;//写操作DriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;//查操作DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = DispatchQueryInfo;//让设备对象知道驱动的位置status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);if (!NT_SUCCESS(status)){KdPrint(("创建设备失败%x\n", status));return status;}status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);if (!NT_SUCCESS(status)){KdPrint(("符号连接创建失败%x\n", status));IoDeleteDevice(DeviceObject);return status;}DeviceObject->Flags |= DO_DIRECT_IO;//mdl直接方式读取//DeviceObject->Flags |= 0;//0表示其他方式读取 配合NeitherRead方法使用DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;pdx = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;pdx->Buffer = (PCHAR)ExAllocatePoolWithTag(PagedPool, 4096, 'a');pdx->Length = 0;return STATUS_SUCCESS;
}

应用层

#include <windows.h>
#include <stdio.h>
#include <winioctl.h>#define IOTEST CTL_CODE(FILE_DEVICE_UNKNOWN,0X800,METHOD_BUFFERED,FILE_ANY_ACCESS)
int main()
{HANDLE hDevice = CreateFile(TEXT("\\\\.\\HelloDDK"),GENERIC_ALL,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);if (hDevice == INVALID_HANDLE_VALUE){printf("设备打开失败%d\n", GetLastError());return -1;}DWORD dwRet;CHAR Buffer[1024] = { 0 };WriteFile(hDevice, "这是一段来自用户层的数据", strlen("这是一段来自用户层的数据"), &dwRet, NULL);printf("驱动提供的地址:%p\n", Buffer);ReadFile(hDevice, Buffer, sizeof(Buffer), &dwRet, NULL);printf("读回来的数据%s\n", Buffer);printf("读取数据的个数%d\n", dwRet);DWORD dwSize = GetFileSize(hDevice, NULL);printf("文件长度%d\n", dwSize);DeviceIoControl(hDevice, IOTEST, NULL, 0, NULL, 0, &dwRet, NULL);CloseHandle(hDevice);return 0;
}

win10驱动开发16——派遣函数(直接方式读操作)相关推荐

  1. 4412开发板学习之Linux驱动开发(八):GPIO读操作与按键轮询实现

    GPIO读操作与按键轮询实现 GPIO读操作 硬件 查找对应IO口 寄存器配置 软件 需要的函数 注册设备 代码及分析 实验效果 按键轮询实现 原理分析 硬件 软件 用到的函数 先前准备工作 代码及分 ...

  2. 嵌入式linux应用层中断函数,嵌入式LINUX驱动开发(中断处理函数)

    嵌入式LINUX驱动开发(中断处理函数) 2020年08月11日 | 萬仟网网络运营 | 我要评论 嵌入式LINUX驱动学习之7中断相关(一)中断处理函数一.函数.头文件及说明二.编译举例:一.函数. ...

  3. Win10驱动开发之开发环境的搭建(一)

    核心内容: 这次学习最后采用的开发环境如下: Windows : win10 64位 1809版本(Host计算机和测试计算机上相同) Visual Studio Community 2017 : 版 ...

  4. 001:VS2019+WDK10+Win10 驱动开发环境

    参考以下两篇文章: Download the Windows Driver Kit (WDK) - Windows drivers | Microsoft Learn <VS2019+WDK10 ...

  5. win10驱动开发19——IRP同步

    这篇文章代码有问题可以参靠这篇 这篇文章 #include <windows.h> #include <stdio.h>void LpoverlappedCompletionR ...

  6. Linux驱动开发16 网络设备驱动框架

    嵌入式下的网络硬件接口         首先,嵌入式网络硬件分为两部分:MAC 和 PHY,大家都是通过看数据手册来判断一款 SOC 是否支持网络,如果一款芯片数据手册说自己支持网络,一般都是说的这款 ...

  7. usb驱动开发16——设备生命线

    回到struct usb_hcd,继续努力的往下看. kref,usb主机控制器的引用计数.struct usb_hcd也有自己专用的引用计数函数,看hcd.c文件: static void hcd_ ...

  8. Win10驱动开发2——双机调试

    双机调试 WinDbug下载地址WDK里面自带该工具 前置环境说明本机有windbug,wmware里面刚安装好win10系统. 设置debug模式 bcdedit bcdedit /dbgsetti ...

  9. win10驱动开发4——加载/卸载驱动

    注意加载卸载驱动必须是win32项目 #include <Windows.h> #include <stdio.h> int main() {//等同于创建驱动======== ...

  10. Linux 驱动开发 三:字符设备驱动框架

    一.参考 (3条消息) Linux 字符设备驱动结构(一)-- cdev 结构体.设备号相关知识解析_知秋一叶-CSDN博客 (3条消息) linux设备驱动框架_不忘初心-CSDN博客_linux设 ...

最新文章

  1. java字符生成器_Java实现简单字符生成器代码例子
  2. hdu 4907(并查集)
  3. Memcached学习笔记 — 第四部分:Memcached Java 客户端-gwhalin(1)-介绍及使用
  4. 学计算机的管理医生,计算机科学与技术系医学生管理工作体会.pdf
  5. 5000字长文 | SaaS盈利的逻辑
  6. mysql normal like_MYSQL语句
  7. 从远程服务器中下载文件到本地
  8. C语言抽签(抽奖)小程序
  9. Python实现电子词典
  10. Brief Summary of Bokeh Effect Rendering
  11. 查找表字段-事务码 AUT10
  12. 系统文件损坏无法正常启动--记一次荡气回肠的自己挖坑自己跳然后爬出来的开心事...
  13. 市场分析-全球与中国木槿果实提取物市场现状及未来发展趋势
  14. C++设计模式-中介者模式详解
  15. 如何做好项目管理任务分配
  16. oracle官方网址
  17. 116. 飞行员兄弟 Java题解
  18. 【RC延迟电路与快速泄放电路】 multisim 14.0仿真 RC延迟电路与快速泄放电路
  19. 吉林建筑大学计算机科学技术,吉林建筑大学计算机科学与技术专业2015年在吉林理科高考录取最低分数线...
  20. python中true用法_使用True/False作为键-如何/为什么这样做?

热门文章

  1. 组装一台计算机需要哪些硬件(写出配置),电脑组装知识网组装电脑配置单中都有哪些配置组装电脑需要的电脑硬件...
  2. smart svn破解
  3. 电脑账户服务器未能登录拒绝访问,win7系统开机提示服务未能登入拒绝访问的解决方法...
  4. Ubuntu 搭建OpenGrok
  5. 利用Python爬取音乐资源,小白福音
  6. android官网m魅族15,魅族15/Plus/Lite等机型现身Android官网:设计惊艳
  7. 腾讯云个人账号实名认证图文详情 新手必看教程
  8. 【白嫖系列-怕违规】告别BDWP龟速下载,体验飞一般的感觉
  9. LeetCode-Python-275. H指数 II
  10. ARTS1(Algorithm, Review , Tip/Techni, Share)