驱动开发之 应用程序通过设备接口打开设备
来源:互联网 发布:python cgi环境搭建 编辑:程序博客网 时间:2024/05/16 14:16
应用程序和设备之间有两种联系方式: 1. 符号链接; 2. 设备接口。
第一种方式符号链接有潜在的安全问题。因为任何内核模式或用户模式程序都能使用这个符号连接打开设备的句柄。
第二种方式设备接口是一种新的设备命名方案,该方案是语言中立的、易于扩展的、可用于许多硬件和软件厂商,并且易于文档化。
现在就来讨论一下怎么利用设备接口使应用程序打开设备
驱动程序中:
1.生成GUID,可利用工具UUIDGEN。GUID(全局唯一标识符),是一种由算法生成的唯一标识。GUID的主要目的是产生完全唯一的数字。在理想情况下,任何计算机和计算机集群都不会生成两个相同的GUID。
先点击New GUID,再点击Copy,然后粘贴到代码中。选择GUID Format 2 ,会生成如下形式的语句
// {3049C680-D73A-4EF6-AA44-AB2EC46F29B7}
DEFINE_GUID(<<name>>,
0x3049c680, 0xd73a, 0x4ef6, 0xaa, 0x44, 0xab, 0x2e, 0xc4, 0x6f, 0x29, 0xb7);
把<<name>>替换为你自己起的名字
DEFINE_GUID(My_Guid,
0x3049c680, 0xd73a, 0x4ef6, 0xaa, 0x44, 0xab, 0x2e, 0xc4, 0x6f, 0x29, 0xb7);
2.注册设备接口
一般在ADDDevice函数中调用
status = IoRegisterDeviceInterface(pdo,&My_Guid,NULL,&deviceExtension->ustrSymLinkName);
3.使能接口
当响应PnP请求IRP_MN_START_DEVICE时,驱动程序将调用IoSetDeviceInterfaceState函数“使能”该接口
status = IoSetDeviceInterfaceState(&deviceExtension->ustrSymLinkName, TRUE);
在响应这个调用过程中,I/O管理器将创建一个指向设备PDO的符号连接对象。以后,驱动程序会执行一个功能相反的调用禁止该接口(用FALSE做参数调用IoSetDeviceInterfaceState)。最后,I/O管理器删除符号连接对象,但它保留了注册表项,即这个名字将总与设备的这个实例关联;但符号连接对象与硬件一同到来或消失。
因为接口名最终指向PDO,所以PDO的安全描述符将最终控制设备的访问权限。这样比较好,因为只有管理员才可以通过控制台控制PDO的安全属性。
禁用接口时调用:status = IoSetDeviceInterfaceState(&deviceExtension->ustrSymLinkName, FALSE);
应用程序中:
//获得类信息 HDEVINFO DevInfo = SetupDiGetClassDevs(&My_Guid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); if(DevInfo==INVALID_HANDLE_VALUE) { printf("SetupDiGetClassDevs error : %d\n", GetLastError() ); return 1; }// Get interface data for the requested instance SP_INTERFACE_DEVICE_DATA InterfaceData; InterfaceData.cbSize = sizeof(InterfaceData); if(!SetupDiEnumDeviceInterfaces(DevInfo, NULL, &My_Guid, 0, &InterfaceData)) { printf("SetupDiEnumDeviceInterfaces error : %d\n", GetLastError() ); SetupDiDestroyDeviceInfoList(DevInfo); return 1; } // 得到 symbolic link name 的长度DWORD ReqLen; SetupDiGetDeviceInterfaceDetail(DevInfo, &InterfaceData, NULL, 0, &ReqLen, NULL); PSP_INTERFACE_DEVICE_DETAIL_DATA InterfaceDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)(new char[ReqLen]); if( InterfaceDetail==NULL) { SetupDiDestroyDeviceInfoList(DevInfo); return 1; } // 得到 symbolic link name InterfaceDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); if( !SetupDiGetDeviceInterfaceDetail(DevInfo, &InterfaceData, InterfaceDetail, ReqLen, NULL, NULL)) { SetupDiDestroyDeviceInfoList(DevInfo); delete InterfaceDetail; return 1; } printf("Symbolic link is %s\n",InterfaceDetail->DevicePath); // 现在可以通过InterfaceDetail->DevicePath打开设备了HANDLE hDevice = CreateFile(InterfaceDetail->DevicePath,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_WRITE|FILE_SHARE_READ,// share mode noneNULL,// no securityOPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL );// no templateprintf("hDevice = %p\n",hDevice);if (hDevice == INVALID_HANDLE_VALUE){printf("Failed to obtain file handle to device: ""with Win32 error code: %d\n", GetLastError() );getchar();return 1;}
- 驱动开发之 应用程序通过设备接口打开设备
- 驱动开发之 驱动设备名称,符号连接名,以及应用程序打开设备
- 通过应用程序使用字符设备驱动
- 第18章 驱动开发之字符设备应用程序
- 设备驱动学习之字符设备驱动接口
- 通过设备链接打开设备
- PCIe驱动开发-设备打开/关闭
- PCIe驱动开发-设备打开/关闭
- linux设备驱动之PCIE驱动开发
- 流接口设备驱动
- 嵌入式linux平台设备驱动(设备驱动模型)开发之linux内核中的设备驱动
- 从应用程序空间打开设备文件到设备驱动的关联过程分析
- linux驱动开发之字符设备--自动创建设备节点
- 字符设备驱动开发之数据结构
- 设备驱动开发之缓冲区读写操作
- Linux设备驱动开发之hello, world
- Arm嵌入式开发之Flash设备驱动
- LINUX之设备驱动开发概述
- maven入门
- linux启动过程详解
- Android 滑动效果进阶篇(五)—— 3D旋转
- 解决html5 / cocos2d-html5乱码的问题
- BTree,B-Tree,B+Tree,B*Tree的数据结构
- 驱动开发之 应用程序通过设备接口打开设备
- linux find 如何排除某些檔案 和 限制尋找層數
- http请求(get 和 post 请求)与响应
- MFC CString转char数组
- linux下oracle11G DG搭建(三):围绕备库搭建操作
- Android 滑动效果进阶篇(六)—— 倒影效果
- WINCE6.0文件系统及存储管理器
- Nginx_lua的测试及选择
- android利用service实现下载apk自动更新功能