博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UMDF
阅读量:6161 次
发布时间:2019-06-21

本文共 8303 字,大约阅读时间需要 27 分钟。

 

 

  看了一周的UMDF,今天就将这些天的心得记下来。

 

  一开始,老大推荐看《竹林蹊径:深入浅出Windows驱动开发完美补全版.张佩马勇董鉴源.扫描版》。这本书看了前三章,这本书讲的太细,作者又奔着深入的想法写的,所以看完后感觉和没看一样,白白浪费一天时间。不过了解了许多基本概念。

 

  后来找到了《Windows 7 Device Driver(Windows 7设备驱动程序开发)》这本书,CSDN上有个带标签的不错,因为我只用到UMDF,所以只看了前两部分,这下我对整个体系结构和程序流程了解多了。这时候MSDN也起到很大的帮助。

 

这本书中有一个对UMDF Driver Skeleton Sample (UMDF Version 1)程序的详解,程序在

可以下载。

 

 

 

上面这些看完后,就打算写个最简单的IOCTL了。但是书上没有例子,只能在网上找了。找到一个

 

 

 

作者写的相当不错,而且有源码可以参考。PS:这是一个系列的,我觉得蛮好的。

 

下面这个是对上面的翻译:

 

 

 

但是我使用的是Windows的UMDF框架,所以还要改变一些。不过也很简单。首先新建一个UMDF框架。然后在Internal.h中添加

#define IOCTL_EXAMPLE_SAMPLE_DIRECT_IN_IO    \        CTL_CODE(FILE_DEVICE_UNKNOWN,        \                 0x800,                      \                 METHOD_IN_DIRECT,           \                 FILE_READ_DATA | FILE_WRITE_DATA)

 

 

然后在IoQueue.cpp中的OnDeviceIoControl函数中添加

//    // Process the IOCTLs    //    switch (ControlCode)    {        case IOCTL_EXAMPLE_SAMPLE_DIRECT_IN_IO:                   OutputDebugString("Hello");              break;            }

在这里一个最简单的IOCTL驱动就写成了,然后就进行Build。

在这里可能会碰到 link error 2019 错误,无法解析的外部命令。这是错误输出框里是哪个函数,很有可能没有VS找不到这个函数的函数库。解决这种问题基本就是三步走:

下面以无法解析setupAPI的某些函数为例:

 

  1. VS2中点击项目 -->右键-->属性-->配置属性-->链接器-->输入-->附加依赖项:将相关的lib文件加入到附加依赖项中: 
  2. 找到setupApi.h所在的目录,我的是在C:\Program Files\Windows Kits\8.0\Include\um。这时候就可以在配置属性-->VC++目录-->包含目录中加入上面的路径。
  3. 找到setupApi.lib所在的目录,注意你所需要时32位的还是64位的版本,我的是32位,所以选择C:\Program Files\Windows Kits\8.0\Lib\win8\um\x86。    这时候就可以在配置属性-->VC++目录-->库目录中加入上面的路径。

 

 第三部新建一个测试工程,我选择的是Win32 console,名字为test。然后在test.cpp中添加

// testapp.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include 
#include
#include
#include
#include "devioctl.h"#include
#define CTL_CODE( DeviceType, Function, Method, Access ) ( \ ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \)#define IOCTL_EXAMPLE_SAMPLE_DIRECT_IN_IO \ CTL_CODE(FILE_DEVICE_UNKNOWN, \ 0x800, \ METHOD_IN_DIRECT, \ FILE_READ_DATA | FILE_WRITE_DATA)////在这里的GUID 应该和Internal中的保持一致//DEFINE_GUID(GUID_DEVINTERFACE_UMDFTestDriver, 0x57bc27d7,0x935c,0x4b57,0x97,0xa3,0x83,0xed,0x17,0x3b,0xbc,0x29);#define countof(x) (sizeof(x) / sizeof(x[0]))_Success_ (return != FALSE)BOOLGetDevicePath( IN LPGUID InterfaceGuid, _Out_writes_(BufLen) PWSTR DevicePath, _In_ size_t BufLen ){ HDEVINFO HardwareDeviceInfo; SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData = NULL; ULONG Length, RequiredLength = 0; BOOL bResult; HRESULT hr; HardwareDeviceInfo = SetupDiGetClassDevs( InterfaceGuid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); if (HardwareDeviceInfo == INVALID_HANDLE_VALUE) { wprintf(L"SetupDiGetClassDevs failed!\n"); return FALSE; } DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); bResult = SetupDiEnumDeviceInterfaces(HardwareDeviceInfo, 0, InterfaceGuid, 0, &DeviceInterfaceData); if (bResult == FALSE) { LPVOID lpMsgBuf; if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR) &lpMsgBuf, 0, NULL )) { printf("SetupDiEnumDeviceInterfaces failed: %s", (LPSTR)lpMsgBuf); LocalFree(lpMsgBuf); } SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); return FALSE; } SetupDiGetDeviceInterfaceDetail( HardwareDeviceInfo, &DeviceInterfaceData, NULL, 0, &RequiredLength, NULL ); DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) LocalAlloc(LMEM_FIXED, RequiredLength); if (DeviceInterfaceDetailData == NULL) { SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); wprintf(L"Failed to allocate memory.\n"); return FALSE; } DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); Length = RequiredLength; bResult = SetupDiGetDeviceInterfaceDetail( HardwareDeviceInfo, &DeviceInterfaceData, DeviceInterfaceDetailData, Length, &RequiredLength, NULL); if (bResult == FALSE) { LPVOID lpMsgBuf; if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR) &lpMsgBuf, 0, NULL)) { printf("Error in SetupDiGetDeviceInterfaceDetail: %s\n", (LPSTR)lpMsgBuf); LocalFree(lpMsgBuf); } SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); LocalFree(DeviceInterfaceDetailData); return FALSE; } hr = StringCchCopy(DevicePath, BufLen, DeviceInterfaceDetailData->DevicePath); if (FAILED(hr)) { SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); LocalFree(DeviceInterfaceDetailData); return FALSE; } SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); LocalFree(DeviceInterfaceDetailData); return TRUE;}HANDLEOpenDevice( _In_ BOOL Synchronous )/*++Routine Description: Called by main() to open an instance of our device after obtaining its nameArguments: Synchronous - TRUE, if Device is to be opened for synchronous access. FALSE, otherwise.Return Value: Device handle on success else INVALID_HANDLE_VALUE--*/{ HANDLE hDev; WCHAR completeDeviceName[MAX_DEVPATH_LENGTH]; if ( !GetDevicePath( (LPGUID) &GUID_DEVINTERFACE_UMDFTestDriver, completeDeviceName, countof(completeDeviceName)) ) { return INVALID_HANDLE_VALUE; } wprintf(L"DeviceName = (%s)\n", completeDeviceName); hDev = CreateFile(completeDeviceName, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, // default security OPEN_EXISTING, ((Synchronous ? FILE_ATTRIBUTE_NORMAL : FILE_FLAG_OVERLAPPED) | SECURITY_IMPERSONATION), NULL); if (hDev == INVALID_HANDLE_VALUE) { wprintf(L"Failed to open the device, error - %d", GetLastError()); } else { wprintf(L"Opened the device successfully.\n"); } return hDev;}int _tmain(int argc, _TCHAR* argv[]){ HANDLE deviceHandle; DWORD code; ULONG index; deviceHandle = OpenDevice(FALSE); if (deviceHandle == INVALID_HANDLE_VALUE) { wprintf(L"Unable to find any OSR FX2 devices!\n"); return FALSE; } if (!DeviceIoControl(deviceHandle, IOCTL_EXAMPLE_SAMPLE_DIRECT_IN_IO, NULL, // Ptr to InBuffer 0, // Length of InBuffer NULL, // Ptr to OutBuffer 0, // Length of OutBuffer &index, // BytesReturned 0)) { // Ptr to Overlapped structure code = GetLastError(); wprintf(L"DeviceIoControl failed with error 0x%x\n", code); } return 0;}

具体可以参考:

 

在这里代码都已经敲完了。需要做的就是将驱动安装上。可以参考这篇:

 OK,接下来就是测试环节,我们使用的是DebugView。可以参考这篇:

最后出现:

就大功告成了!!

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/SpeakSoftlyLove/p/3433808.html

你可能感兴趣的文章
thead 固定,tbody 超出滚动(附带改变滚动条样式)
查看>>
Dijkstra算法
查看>>
css 动画 和 响应式布局和兼容性
查看>>
csrf 跨站请求伪造相关以及django的中间件
查看>>
MySQL数据类型--与MySQL零距离接触2-11MySQL自动编号
查看>>
生日小助手源码运行的步骤
查看>>
Configuration python CGI in XAMPP in win-7
查看>>
bzoj 5006(洛谷 4547) [THUWC2017]Bipartite 随机二分图——期望DP
查看>>
CF 888E Maximum Subsequence——折半搜索
查看>>
欧几里德算法(辗转相除法)
查看>>
面试题1-----SVM和LR的异同
查看>>
MFC控件的SubclassDlgItem
查看>>
如何避免历史回退到登录页面
查看>>
《图解HTTP》1~53Page Web网络基础 HTTP协议 HTTP报文内的HTTP信息
查看>>
unix环境高级编程-高级IO(2)
查看>>
树莓派是如何免疫 Meltdown 和 Spectre 漏洞的
查看>>
雅虎瓦片地图切片问题
查看>>
HTML 邮件链接,超链接发邮件
查看>>
HDU 5524:Subtrees
查看>>
手机端userAgent
查看>>