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

原创 2016年03月08日 09:33:52

本文作者: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函数中的参数是定义在硬件的驱动程序里的。
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

C语言竟是如何调用硬件的

大家都知道我们可以使用C语言写一段程序来控制硬件工作,但你知道其工作原理吗? 网友北极 C语言在实际运行中,都是以汇编指令的方式运行的,由编译器把C语言编译成汇编指令,CPU直接执行汇...

.net应用程序如何批上XP的外衣?

net framework 所提供的开发控件也太少了,也太难看了,自已画又费时费力也不见得会得出个什么好的效果。如果能够上我们的程序运行在XP环境中能自动应用XP的主题样式那就省时多了,让MICROS...

中兴2016校招软件在线笔试题

本文转自:http://blog.csdn.net/dandelion1314/article/details/47805567#comments 据说今年是中兴的第一次在线笔试,摄...
  • Cowena
  • Cowena
  • 2015-08-21 13:50
  • 10193

三招可纠正宝宝“吮指癖” 问答大全

大多数小儿都有吃手指的偏好,添加辅食以后更加突出。当宝宝可以下地活动,而吮吸已经弄脏的小手时,家长的担忧便与日俱增。用什么办法治这“吮指癖”?专家指出,纠正孩子吃手指的不良习惯,应以教育和转移注意力为...

C语言直接驱动硬件实现PC机的串口操作

熟悉C语言的人都知道,虽然C语言是一门高级语言,拥有很多高级语言的特性,但是作为一种由低级语言到高级的过渡,他又继承了很多低级语言的特性,那就是可以直接操作计算机的硬件设备。本人近日在学习有关PLC网...

Windows应用程序,操作系统,计算机硬件之间的相互关系

1、应用程序通过Windows API调用操作系统函数从而和计算机硬件交互,如空中声卡发出什么样的声音 2、计算机硬件将信息发送给操作系统,而操作系统将消息传给应用程序并进入消息循环处理,消息处理过程...

(键盘)代码 19:由于其配置信息(注册表中的)不完整或已损坏,Windows 无法启动这个硬件设备 解决方法

VMware没卸载就让我直接删除掉了。在删除VMware一些残留的服务后,结果重新启动系统后,键盘不能用了,一敲键盘后,鼠标也不动了,造成系统假死状态。如果不动键盘,鼠标仍然可以使用,关掉系统,重新插...

(键盘)代码 19:由于其配置信息(注册表中的)不完整或已损坏,Windows 无法启动这个硬件设备 解决方法

VMware没卸载就让我直接删除掉了。在删除VMware一些残留的服务后,结果重新启动系统后,键盘不能用了,一敲键盘后,鼠标也不动了,造成系统假死状态。如果不动键盘,鼠标仍然可以使用,关掉系统,重新插...

(键盘)代码 19:由于其配置信息(注册表中的)不完整或已损坏,Windows 无法启动这个硬件设备

无奈只能用鼠标查找故障。打开设备管理器看到键盘那项里是一个惊叹号! 查看详细信息: 设备管理器显示:代码 19:由于其配置信息(注册表中的)不完整或已损坏,Windows 无法启动这个硬件...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)