Windows下C语言操作硬件设备的方法

2023-11-17

本文作者:Fezl

本文原地址:http://blog.csdn.net/u010147522/article/details/49912221



之前都是在linux下操作硬件设备,open、read、write、ioctl,相当方便。

最近要检测windows的驱动程序有没有问题,于是得写个简单的程序测试一下设备的ioctl功能。


说一下windows下操作设备的大体方法:

1. 用设备的GUID来获取设备的路径path

2. 用设备路径来打开设备,获得HANDLE

3. 用HANDLE进行ioctl


大体思路跟Linux差不太多。贴上代码


#include <stdio.h>
#include <objbase.h>
#include <WinBase.h>
#include <SetupAPI.h>	//setupapi.lib
#include "public.h"

#define INTERFACE_DETAIL_SIZE   (1024)

int main()
{
	HANDLE hDevice = NULL;
	HDEVINFO hDevInfo = NULL;
	PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail = NULL;
	GUID guid = {0x57415445, 0x5254, 0x454b, 0x44, 0x52, 0x49, 0x56, 0x45, 0x52, 0x43, 0x24};
	INT nCount, i;
	BOOL bResult;
	CHAR devPath[MAX_PATH];
	SP_DEVICE_INTERFACE_DATA ifdata;
	DWORD outBuffer[512] = { 0 };
	DWORD inBuffer[512];
	DWORD returnBytes = 0;


	memset(inBuffer, 1, 512);
	hDevInfo = SetupDiGetClassDevs(
		&guid, 
		NULL, 
		NULL, 
		DIGCF_PRESENT | DIGCF_DEVICEINTERFACE
		);
	if (hDevInfo == INVALID_HANDLE_VALUE)
	{
		printf("Error: SetupDigetClassDevs .\n");
		return -1;
	}
	printf("OK --- SetupDiGetClassDevs.\n");
 
	// 申请设备接口数据空间   
	pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)GlobalAlloc(LMEM_ZEROINIT, INTERFACE_DETAIL_SIZE);

	pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

	nCount = 0;
	bResult = TRUE;

	// 设备序号=0,1,2... 逐一测试设备接口,到失败为止   
	while (bResult)
	{
		ifdata.cbSize = sizeof(ifdata);

		// 枚举符合该GUID的设备接口   
		bResult = SetupDiEnumDeviceInterfaces(
			hDevInfo,            // 设备信息集句柄   
			NULL,                   // 不需额外的设备描述   
			&guid,                 // GUID   
			(ULONG)nCount,          // 设备信息集里的设备序号   
			&ifdata);               // 设备接口信息   
		
		if (bResult)
		{
			// 取得该设备接口的细节(设备路径)   
			bResult = SetupDiGetInterfaceDeviceDetail(
				hDevInfo,            // 设备信息集句柄   
				&ifdata,                // 设备接口信息   
				pDetail,                // 设备接口细节(设备路径)   
				INTERFACE_DETAIL_SIZE,  // 输出缓冲区大小   
				NULL,                   // 不需计算输出缓冲区大小(直接用设定值)   
				NULL);                  // 不需额外的设备描述   

			if (bResult)
			{
				strcpy(devPath, pDetail->DevicePath);
				printf("lenth = %d\nDevicePath: %s\n\n", strlen(devPath), devPath);
				nCount++;
			}
		}
		else
		{
			printf("error: %d\n", GetLastError());
		}
	}

	hDevice = CreateFile(
		devPath,
		GENERIC_READ | GENERIC_WRITE,
		0,
		NULL,
		OPEN_EXISTING,
		0,
		NULL
		);
	if (hDevice == INVALID_HANDLE_VALUE)
	{
		printf("Error: CreateFile. code = %d\n", GetLastError);
		return -2;
	}
	printf("OK --- CreateFile.\n");


	printf("Bytes = %d,  outBuffer; %s\n", returnBytes, outBuffer);


	bResult = DeviceIoControl(
		hDevice,
		WTDRIVER_MEMORY_WRITE_BAR1,
		inBuffer, 256,
		NULL, 0,
		&returnBytes,
		NULL
		);
	if (!bResult){
		printf("Error: DeviceIoControl.");
		return -3;
	}

	bResult = DeviceIoControl(
		hDevice,<span style="white-space:pre">			</span>//设备句柄
		WTDRIVER_MEMORY_READ_BAR1,<span style="white-space:pre">	</span>//读BAR1
		NULL, 0,
		outBuffer, 256,<span style="white-space:pre">			</span>//读在outBuffer里,读256个字节
		&returnBytes,<span style="white-space:pre">			</span>//实际读取字节数
		NULL
		);
	if (!bResult){
		printf("Error: DeviceIoControl.");
		return -3;
	}

	printf("Bytes = %d\n", returnBytes);
	for (i = 0; i < returnBytes; i++)
	{
		printf("%d: outBuffer: %#x\n", i, outBuffer[i]);
	}

	CloseHandle(hDevice);
	// 释放设备接口数据空间   
	GlobalFree(pDetail);
	// 关闭设备信息集句柄   
	SetupDiDestroyDeviceInfoList(hDevInfo);


	system("pause");
	return 0;
}


其中的publi.h只是我要操作的这个设备特有的头文件。


DeviceIoControl函数中的参数是定义在硬件的驱动程序里的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Windows下C语言操作硬件设备的方法 的相关文章

  • Windows - 启动时自动启动特定应用程序

    在 Windows 操作系统中开发信息亭应用程序 当机器启动时 必须依次发生 3 件事 Node js 服务器启动 包含 Web 应用程序的浏览器以 kiosk 模式启动 另一个客户端应用程序启动 是否有一个实用程序可以轻松完成此操作 或者
  • std::string 到 LPCTSTR

    新版本典型问题如何转换而来std string to LPCTSTR 从不同的帖子中我了解到我应该这样做 CreateDirectory path c str NULL 编译器仍然给出错误 因为cannot convert from con
  • php.ini 在哪里? [复制]

    这个问题在这里已经有答案了 我运行 phpinfo 它说它在 C Windows 中 但它不在那里 它不在 php 文件夹中 我系统搜索了一下 没有找到 它藏在哪里 运行此代码 我假设您的 php 正在运行 您无法仅找到 php ini 文
  • Inno Setup中如何处理带空格的路径?

    我想允许带有空格的路径 例如program files 当使用 Inno Setup 安装我的程序时 但是 带有空格的路径会让我安装的服务崩溃 Inno 安装文件如下所示 Setup AppName Demo DefaultDirName
  • Anaconda (Python) - Windows 10 上的 Cmder 集成

    我在 Windows 10 64 位上通过 Anaconda 让 Cmder 使用 Python 时遇到了一些麻烦 我让 Anaconda 工作得很好 测试过用 matplotlib 绘制一些东西 它与 Anaconda Prompt 一起
  • 如何使用WAMP登录phpMyAdmin,用户名和密码是什么?

    根 这个词是什么意思php我的管理员 http en wikipedia org wiki PhpMyAdmin 每当我写作时localhost phpmyadmin在地址栏上 我被要求输入用户名和密码 但我不知道它们是什么 我不记得何时何
  • 使用 CMake 和 clang 在 Windows 上构建简单的 C++ 项目

    我正在尝试在 Windows 10 上构建一个简单的 Hello World 程序 最好使用 CMake 和 clang 如果我使用 MinGW 的 g 编译器 我可以成功编译 链接和运行同一个项目 但当我尝试使用 clang 时会遇到问题
  • Git,无法在 Windows 上克隆存储库

    我正在尝试在 Windows 上使用 git 克隆远程存储库 我可以在我的 mac 上克隆它 但在 Windows 上我遇到了问题 当使用 git bash 克隆时 我收到一条消息 指出服务器的主机密钥未缓存在注册表中 它要求我按 y 或
  • C++:获取注册表值仅给出第一个字符[重复]

    这个问题在这里已经有答案了 我试图从注册表中获取字符串值 但我只得到第一个字母 HKEY hKey char gamePath MAX PATH if RegOpenKeyEx HKEY CURRENT USER L Software Bl
  • 在 R 中查找 Windows 用户名

    有没有办法在 R 会话中获取当前的 Windows 用户名或 Windows 主目录 Thanks 抱歉 如果我错过了什么 但我找不到任何东西 你可以做 Sys getenv USERNAME Sys getenv HOME 如果你只是输入
  • 将 SQL 数据库附加到 ComboBox.ItemSsource (WPF)

    我想知道如何将 SQL Server 数据库分配给 ComboBox 的 ItemSource 属性 在 WPF 应用程序中 我将数据源分配给项目 但不知道如何分配给属性 此致 你可以这样尝试 你可以像下面这样绑定组合框的项目源属性 Ite
  • 同时触发 Windows 事件 id 4802 和 4803(调用和取消屏幕保护程序)

    事件 id 4803 关闭屏幕保护程序 在事件 id 4802 调用屏幕保护程序 之后立即触发 请注意 屏幕保护程序实际上仍然处于打开状态 直到检测到用户交互 我使用的是 Windows 8 1 在 Windows 7 上 事件 id 48
  • .NET 进程分配的内存何时释放回 Windows

    设置 NET 在启动时以及在收集后尝试满足分配请求时 分段为每一代的堆 0 1 2 LOH 分配内存 以获得连续的内存块 为每个堆分配的内存可能会随着应用程序 预热 而趋于平稳 但第 2 代和大型对象堆可能除外 在垃圾收集期间 每个堆 0
  • 使用 std::string 导致 Windows“找不到入口点”[重复]

    这个问题在这里已经有答案了 当我用 G C C 编译它时 include
  • 如何使用 winrar 提取与 zip 文件同名的文件夹中的所有 zip 文件?

    我需要迭代一个文件夹 对于每个 zip 文件 我需要使用它的名称来提取它 也就是说 如果它是 test zip 那么它应该解压到 test 文件夹 同样 它应该迭代我的文件夹及其子文件夹并提取内容 我编写了下面的代码 但它没有使用 zip
  • 什么进程正在使用给定的文件?

    我的一个脚本遇到了问题 它似乎无法规律地写入自己的日志 并抛出错误 此文件正在被另一个进程使用 我知道有一些方法可以用 try excepts 来处理这个问题 但我想知道why这种情况正在发生 而不仅仅是掩盖它 根本不应该有任何其他东西访问
  • Python:导航到便携式设备目录 (Windows 7)

    我正在尝试解决我创建的一个问题 https stackoverflow com questions 21381652 python find record time of mp4 movie noredirect 1 comment3234
  • REG ADD - 语法无效

    我试图通过在批处理文件中使用以下代码行来修改注册表中的值 但当我在参数周围使用双引号时 我不断收到 错误 语法无效 而当我使用单引号时 我不断收到 无效的键名 REG ADD HKLM SOFTWARE Microsoft Windows
  • Windows 上的 OpenGL SDK

    我正在尝试编写一个 OpenGL 应用程序 因此我安装了 Windows 7 SDK 然而 它似乎是OpenGL 1 1 define GL VERSION 1 1 1 如何找到我安装的 OpenGL 版本 dll 以及在哪里可以找到较新的
  • 使用 Windows 电源管理 API 调暗显示器

    我正在尝试做一些看起来很简单的事情 我只想让我的程序能够在某些条件下调整显示器亮度 于是 我向窗户望去电源管理API http msdn microsoft com en us library aa373163 28v vs 85 29 a

随机推荐

  • 秒天秒地!黑马王炸学科,均薪18k+,最高42000元!

    掌握AI的同学 握住了高薪密码 黑马北京校区人工智能开发 16 班的就业炸了 毕业仅 7 个工作日 班级就业率便达到 65 班级均薪高达 18340 9 元 最高薪资更是冲到了 42k 班级就业详情数据 滑动沾高薪喜气 看完这无敌的就业喜报
  • Three.js使用OrbitControls后修改相机旋转方向无效

    1 问题复现 在项目中添加了OrbitControls控制器来控制相机的旋转和平移 但是需要修改初始的相机角度 于是我把相机的角度进行修改 如下 const camera new THREE PerspectiveCamera 75 vie
  • linux nginx 配置

    http blog csdn net Colton Null article details 78439174 locationNum 8 fps 1 之前发布过一篇如何在Tomcat中配置二级域名 现在发现几个月前的我太年轻了 哎 过几个
  • Leetcode算法——63、不重复路径II(unique paths II)

    一个机器人位于一个m n的网格的左上角 它每次只能向下或向右移动一格 它试图到达网格的右下角 网格中有一些障碍物 机器人不能通过 求有多少种不重复的路径 备注 1 m 和 n 都不大于 100 2 障碍物和空地分别被标为 1 和 0 示例
  • 如何开发一个小程序游戏?

    小程序游戏开发需要开发人员具备以下几点能力 有一定的编程基础 例如 JavaScript TypeScript 至少熟悉一种游戏开发引擎 比如 Cocos Unity等 对游戏机制 游戏系统有一定的理解 有一定的 UI 界面审美 能够开脑洞
  • 字典树Trie和三叉搜索树Ternary Tree的学习总结

    字典树Trie和三叉搜索树Ternary Tree的学习总结 出处 西西整理 作者 西西 日期 2012 12 31 2 39 04 大 中 小 评论 0 我要发表看法 Trie树 又称字典树 单词查找树或者前缀树 是一种用于快速检索的多叉
  • 第38讲 Android Camera2 API 通过CropRegion控制Zoom缩放

    本讲是Android Camera专题系列的第38讲 我们介绍Android Camera2 API专题的通过CropRegion控制Zoom缩放 包括如下内容 Android Zoom简介 如何查询当前Camera支持的Zoom能力 通过
  • pycharm中from,import文件/模块出现问题(最全方法)

    1 引用本地文件 如上图所示 在pycharm中可能会出现引用 本地项目文件夹中的 py文件出现问题的时候 这时我们需要考虑是否是IDE环境未将项目路径设置到引用环境变量中 有一下几种方法可以解决 1 这时可以通过sys path inse
  • iOS开源系列——OC框架排名列表

    Objective C框架排名 快点我
  • PRD文档范例,产品经理值得收藏的写作手册

    2015年 我写了一篇梳理PRD的文章 PRD到底该怎么写 获得3 5万次阅读 423次收藏 至今已过去5年 在这5年里 我一直从事产品产品相关的工作 也经历过一次完整的创业 对PRD又有了一些新的思考 这篇文章是 PRD怎么写 的升级版
  • 软件测试方法——静态测试与动态测试

    从测试方法的角度可以分为手工测试和自动化测试 1 静态测试 所谓静态测试 static testing 就是不实际运行被测软件 而只是静态地检查程序代码 界面或文档中可能存在的错误的过程 从概念中我们可以知道 其包括对代码测试 界面测试和文
  • Python re.match函数的使用详解

    正则表达式是用于匹配和操作文本的强大工具 在Python中 re模块提供了一组函数来处理正则表达式 其中 re match函数用于尝试从字符串的起始位置匹配一个模式 本文将详细介绍re match函数的使用方法 并提供相应的源代码示例 re
  • MiniDump不生成或者生成0字节

    今天在使用C写一个Windows多线程程序时 发现退出过程中有段错误 为了方便快速的定位问题 我使用了MiniDump MiniDump c源码如下 include
  • 2021年系统集成项目管理工程师(软考中级)连夜整理考前重点

    一 信息与信息化 1 信息论奠基者香农认为 信息就是能够用来消除不确定性的东西 8种状态需要3位比特表示 5位比特则可表示64种状态 信息 物质材料 能源是三大戓略资源 2 信息论两个层次 本体论和认识论 3 信息传输模型 信源 编码 信道
  • Qt鼠标单击与长按

    在Qt中 可以通过重载QWidget的mousePressEvent mouseReleaseEvent 和mouseMoveEvent 等事件来实现对鼠标事件的处理 判断鼠标是长按还是点击 可以通过记录鼠标按下的时间和释放的时间 通过两个
  • 15.DDT+unittest+excel ddt框架结合单元测试

    Excel读取数据的三种方式 1 一次性读取所有的数据 对内存的要求高点 必须掌握 2 需要用的时候读取所有的数据 就是磁盘读写要求高点 磁盘 速度最低 内存 速度中间 CPU 速度最高 3 使用DDT进行参数化 方法一 一次性读取所有的数
  • 缓存相关

    缓存雪崩怎么解决 如果缓存因为某个原因不可用 导致大量请求涌向数据库 可能会导致数据库崩溃 缓存雪崩目前主要有两种方案 1 使用集群 集群部署缓存 当一台宕机时 其他机器仍能提供缓存服务 2 Hystrix 熔断器 起到熔断 降级 限流三个
  • 文章内容无法复制复制不了

    一些文档 什么的复制不了 主要有几种方法 目录 1 禁用js 2 ctrl P打印 3 选中要复制的内容 gt 拖到网址输入框 另外 通过一些浏览器插件 感觉用处不大 1 禁用js 优点 可以直接复制原有段落文字的格式 缺点 有点麻烦 对百
  • 通俗理解三大范式

    关系型数据库中我们用的最多的就是第一范式 1NF 第二范式 2NF 第三范式 3NF 所以需要我们深入理解三大范式 第一范式 1NF 要求数据库的每一列都是不可分割的原子数据项 在上面的表中 家庭信息 和 学校信息 列均不满足原子性的要求
  • Windows下C语言操作硬件设备的方法

    本文作者 Fezl 本文原地址 http blog csdn net u010147522 article details 49912221 之前都是在linux下操作硬件设备 open read write ioctl 相当方便 最近要检