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

一个分布式服务器集群架构方案

0x01.大型网站演化 简单说,分布式是以缩短单个任务的执行时间来提升效率的,而集群则是通过提高单位时间内执行的任务数来提升效率。 集群主要分为:高可用集群(High Availability C...

bufToHexStr的C++实现------将buffer转为对应的16进制形式(与坑同在)

bufToHexStr还是很常见的, 也非常常用, 写个代码玩玩(别乱拷贝如下代码): #include #include using namespace std; string bufToHe...
  • stpeace
  • stpeace
  • 2016年06月26日 23:24
  • 1183

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

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

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

无奈只能用鼠标查找故障。打开设备管理器看到键盘那项里是一个惊叹号! 查看详细信息: 设备管理器显示:代码 19:由于其配置信息(注册表中的)不完整或已损坏,Windows 无法启动这个硬件...

Optix155_622硬件设备

  • 2013年10月19日 21:57
  • 5.22MB
  • 下载

微信蓝牙硬件设备接入(1)

微信jsapi是网页javascript的接口,该接口允许厂商的网页对局域网设备(设备必须支持AirKiss3.0)和蓝牙设备进行操作。例如扫描设备,连接设备,收发数据,绑定设备等。大概流程图如下(以...

网络硬件设备完全技术宝典-第三版

  • 2014年12月17日 11:21
  • 267.97MB
  • 下载

Cisco Security CCIE V4 硬件设备清单

  • 2013年04月30日 20:55
  • 86KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Windows下C语言操作硬件设备的方法
举报原因:
原因补充:

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